0

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?

bluehallu
  • 10,205
  • 9
  • 44
  • 61
Harry
  • 13,091
  • 29
  • 107
  • 167

2 Answers2

1

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.

bluehallu
  • 10,205
  • 9
  • 44
  • 61
  • Thanksf or explaining what you did, that really helps – Harry Jul 18 '13 at 16:24
  • It makes no sence to me, how will this be saved? I mean I want to add a subsidiary to a company. SO I see a company and then choose from a list the subsidiary(ies). In this case it seems like I will always set the parent_id, so reversing the process – Harry Jul 18 '13 at 22:08
  • I've edited your question tags so you realise your problem is completely about database design and not about ruby. This is a simple one-to-many recursive relation and is represented the way I told you: http://www.tomjewett.com/dbdesign/dbdesign.php?page=recursive.php – bluehallu Jul 19 '13 at 06:31
1

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
sites
  • 21,417
  • 17
  • 87
  • 146
  • 1
    Lol we posted the same solution with just 9 seconds of difference, I was first! :D – bluehallu Jul 18 '13 at 15:02
  • 1
    heheh, I posted when I saw `I new quiestion...` – sites Jul 18 '13 at 15:04
  • Thanks for this, both the same, but you gave more so Ill make you the correct one, though both are correct! – Harry Jul 18 '13 at 16:25
  • When I do this : <% @companies.each do |company| %>
  • <%= link_to "#{company.name} #{company.subsidiaries.length > 0 ? "(#{company.subsidiaries.length} subsidiaries)" :"" }", company_path(@company, :id => company.id) %><% end %> It shows me the companies with subsidiaries as the companies who have parent_id's. THat is not correct
  • – Harry Jul 18 '13 at 19:07
  • I have a typo in my response. `foreign_key: :parent_id` – sites Jul 18 '13 at 19:19
  • I think I don't understood "It shows me the companies with subsidiaries as the companies who have parent_id" you mean who have parent_id equal to something or different to nil or do you mean another thing? – sites Jul 18 '13 at 19:21
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/33719/discussion-between-harry-and-juanpastas) – Harry Jul 18 '13 at 19:27
  • Do you see what I mean? – Harry Jul 18 '13 at 19:39