Awesome thank you so much, I had come to that conclusion although it
didn't seem natural.
This is what my spec looks like, I think its correct:

Database Associations

What we want:

There are users, construction companies, real state companies and
natural persons. A user controls one of the 3 entities(construction
companie, real state company or natural person). And each of this
entities has listings, and in the case of construction company also
projects. The relationships are as followed:

1. user has_one :construction_company or :real_state_company
or :natural_person

2. construction_company has_many ---> :projects which has_many ---> :
listings

3. real_state company has_many ----> :listing

4. natural_person has_one----> :listings



How this looks in code:

We need to use polymorphic associations to be able to express this
relationships, because for example listings belongs to all 3 type of
entities, thus listings has to be polimorphic.

:listings belongs to-> projects, real_state_company, natural_person

We start by looking at what this 3 entities have in common, mainly
that they are the sellers, so we will add to the databes a foreign key
that lists the seller identification(seller_id) and which type of
seller he is(construction company or real state company etc).

In rails this is accomplished by:

$rails generate model Listing …. seller_id:integer seller_type:string

This will ad a seller_id and seller_type to the migrations. Rails has
a way of simplifying this by replacing the 2 keys with:

t.references :seller, :polymorphic => true
which will create both keys for use.

After, inside the listing model then we can say that the listing
belongs to a seller instead of explicitly saying which
seller(company....) this is expressed using the following code

class Listing < ActiveRecord::Base

    belongs_to :seller, :polymorphic => true

end

Then we can add the relationship to each one of the entities using :as

class Real_State_Company < ActiveRecord::Base

    has_many :listings, :as => :seller

end


Until here we have taken care of the relationship were a listing
belongs to any 3 entities(projects, real_state_company and
natural_person). Now we need to look at the case were the construction
company, real state company or natural user belongs to a User. Since
this is the reverse, we start looking what does the user has, he
has_one of the 3 things(company, real state company or
natural_person), we'll call this entities, thus in rails we can say:

class User < ActiveRecord::Base

    has_one :entity, :polymorphic => :true

end

And then each of the entities will have:

class Real_State_Company < ActiveRecord::Base

    belongs_to :user, :as => :entity

end

We need to modify the user model with entity_id and entity_type, or:

t.references :entity, :polymorphic => true


Unfortunatelly has_one polymorphic is not supported, therefore we need
to think in reverse.




class User < ActiveRecord::Base

   belongs_to :ownable, :polymorphic => :true

end

And then each of the entities will have:

class Real_State_Company < ActiveRecord::Base

    has_one :user, :as => :ownable

end

We need to modify the user model with entity_id and entity_type, or:

t.references :entity, :polymorphic => true


Then to get if the user owns a company or natural person do
@user.ownable, similary to see which user owns a company
@company.user.



On Nov 1, 1:15 pm, Tim Shaffer <timshaf...@me.com> wrote:
> Yup, then like Marnen said, Person should belong to Item:
>
>   belongs_to :item, :polymorphic => true
>
> In your migration, you can use:
>
>   t.references :item, :polymorphic => true
>
> Which will create item_type and item_id columns.
>
> Then each class A, B, and C can have one person:
>
>   has_one :person, :as => :item

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Talk" group.
To post to this group, send email to rubyonrails-t...@googlegroups.com.
To unsubscribe from this group, send email to 
rubyonrails-talk+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-talk?hl=en.

Reply via email to