Harry
Harry

Reputation: 13329

Rails models has_many

Im starting to learn rails today and not quite sure how this would work:

Lets say I have a Company, the company may have many subsidiaries.

A subsidiary is a Company. A company cannot be its own subsi diary for obvious reasons.

A subsidiary cannot have a subsidiary that is also a subsidiary of the company

So a subsidiary can also have subsidiaries, so its unlimitedly nested

what im also not sure about below is that a subsidiary is a company

class Company < ActiveRecord::Base
    has_many :subsidiaries
end
class Subsidiary < ActiveRecord::Base
    belongs_to :companies
end

Im sure this is so wrong, just putting something in here

UPDATE:

Ok, so I followed the instructions below like this:

class Company < ActiveRecord::Base
    validates   :name, presence: true
    belongs_to :company
    has_many :subsidiaries, foreign_key: 'company_id', class_name: 'Company'
end

In one of my templates:

<% @companies.each do |company| %>
    <li><%= link_to  "#{company.name} #{company.subsidiaries.length > 0 ? "(#{company.subsidiaries.length} subsidiaries)" :"" }", company_path(@company, :id => company.id) %></td>
<% end %>

Now this is show wrong, what happens is that the Ones with subsidiaries shows they have no subsidiaries and the ones who are subsidiaries shows they have subsidiaries, SO basicly its showing its parent's now, its "children"

ANy idea why this happens?

Upvotes: 0

Views: 136

Answers (2)

sites
sites

Reputation: 21815

I would use

class Company < ActiveRecord::Base
  has_many   :subsidiaries, class_name: 'Company', foreign_key: :parent_id
  belongs_to :parent, class_name: 'Company'
end

To use these relations you will need parent_id column in your table:

rails g migration add_parent_id_to_companies parent_id:ineteger
rake db:migrate

You would use like this:

          A
        /   \
       /     \
      B       C
     / \
    /   \
   D     E


A.subsidiaries => [B,C]
B.subsidiaries => [D,E]
C.subsidiaries => [] # actually a relation without results
B.parent => A
C.parent => A
A.parent => nil
D.parent => B

Upvotes: 1

bluehallu
bluehallu

Reputation: 10295

What you want is a recursive self relation:

class Company < ActiveRecord::Base
    belongs_to :company
    has_many :subsidiaries, foreign_key: 'company_id', class_name: 'Company'
end

So, essentially, a company belongs to a company and has many companies. However, we have a special name for it's companies (subsidiaries), so we give it this "alias" by manually setting the relation. You might want to do the same for the "parent" company.

You would then use validations to check all those conditions.

Upvotes: 1

Related Questions