ruby-on-railsactiverecordrails-activerecordactiveadminrails-models

Define a nested has_many and belongs_to


Let's suppose I have 3 models, A, B and C (where A has many B, and B has many C):

class A < ActiveRecord::Base
  has_many :bs
end

class B < ActiveRecord::Base
  belongs_to :a
  has_many :cs
end

class C < ActiveRecord::Base
  belongs_to :b
end

So here everything works fine. With A.first.bs I get all the instances of B associated with the first instance of A, with C.last.b I get the instance of B associated with the last instance of C, etc.

But want to be able to be able to do A.first.cs and C.last.a, how can I do this?

I want to do this because I want to be able to do C.all.joins(:a) because I want to graph some statistics about instances of C, grouped by A. Is there another way to do the same?


Solution

  • Just create indirect associations that traverse the tree.

    class A < ApplicationRecord
      has_many :bs
      has_many :cs, through: :bs
    end
    
    class B < ApplicationRecord
      belongs_to :a
      has_many :cs
    end
    
    class C < ApplicationRecord
      belongs_to :b
      has_one :a, through: :b
    end
    

    This will let you go from either end:

    A.first.cs
    C.last.a 
    # etc
    

    ActiveRecord will automatically join the intermediate model (B).