So here is a sample class
class Company < ActiveRecord::Base
has_many :investments
has_many :vc_firms, through: :investments, source: :investor, source_type: 'VentureFirm'
has_many :angels, through: :investments, source: :investor, source_type: 'Person'
end
@company.angels and @company.vc_firms works as expected. But how would I have @company.investors that are comprised of both source types? That would work for all polymorphics on the investor column of the Investments table? or perhaps a way of using a scope to merge all source_type?
Investment model looks like this:
class Investment < ActiveRecord::Base
belongs_to :investor, polymorphic: true
belongs_to :company
validates :funding_series, presence: true #, uniqueness: {scope: :company}
validates :funded_year, presence: true, numericality: true
end
Angels are associated through the Person model
class Person < ActiveRecord::Base
has_many :investments, as: :investor
end
Relevant financial organization model associations:
class FinancialOrganization < ActiveRecord::Base
has_many :investments, as: :investor
has_many :companies, through: :investments
end
Such customizations can easily be accomplished by passing options and scope blocks when you create the association. For example, this association uses two such options: If you set the :autosave option to true, Rails will save any loaded association members and destroy members that are marked for destruction whenever you save the parent object.
For example, consider a simple Rails application that includes a model for authors and a model for books. Each author can have many books. Without associations, the model declarations would look like this:
Rails offers two different ways to declare a many-to-many relationship between models. The first way is to use has_and_belongs_to_many, which allows you to make the association directly: class Assembly < ApplicationRecord has_and_belongs_to_many :parts end class Part < ApplicationRecord has_and_belongs_to_many :assemblies end
While Rails uses intelligent defaults that will work well in most situations, there may be times when you want to customize the behavior of the has_many association reference. Such customizations can easily be accomplished by passing options when you create the association. For example, this association uses two such options:
Previous solution was wrong, I misunderstood one of the relations.
Rails cannot provide you with a has_many method crossing a polymorphic relation. The reason is that the instances are spread out through different tables (because they can belong to different models which might or not be on the same table). So, you must provide the source_type if you cross a belongs_to polymorphic relation.
Having said that, supposing you could use inheritance in the Investor like this:
class Investor < ActiveRecord::Base
has_many :investments
end
class VcFirm < Investor
end
class Angel < Investor
end
The you would be able to remove the polymorphic option from investments:
class Investment < ActiveRecord::Base
belongs_to :investor
belongs_to :company
.........
end
And you would be able to cross the relation and scope it with conditions:
class Company < ActiveRecord::Base
has_many :investments
has_many :investors, through :investments
has_many :vc_firms, through: :investments, source: :investor, conditions: => { :investors => { :type => 'VcFirm'} }
has_many :angels, through: :investments, source: :investor, conditions: => { :investors => { :type => 'Angel'} }
end
I added a method to the Company
class that fetches all investors for the company by joining with the investments table:
class Company < ActiveRecord::Base
has_many :investments
has_many :vc_firms, :through => :investments, :source => :investor, :source_type => 'VcFirm'
has_many :angels, :through => :investments, :source => :investor, :source_type => 'Angel'
def investors
Investor.joins(:investments).where(:investments => {:company_id => id})
end
end
http://www.brentmc79.com/posts/polymorphic-many-to-many-associations-in-rails looked pretty helpful for reading up on :source
vs. :source_type
.
Hope it helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With