【问题标题】:Rails has_many through aliasing with source and source_type for multiple typesRails has_many 通过为多种类型使用 source 和 source_type 的别名
【发布时间】:2013-07-06 15:35:21
【问题描述】:

所以这里是一个示例类

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 和 @company.vc_firms 按预期工作。但是我如何拥有由两种来源类型组成的@company.investors?这适用于 Investments 表的 Investor 列上的所有多态性吗?或者也许是一种使用范围来合并所有 source_type 的方法?

投资模型如下:

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

天使通过 Person 模型关联

class Person < ActiveRecord::Base
    has_many :investments, as: :investor
end

相关金融组织模型协会:

class FinancialOrganization < ActiveRecord::Base
    has_many :investments, as: :investor
    has_many :companies, through: :investments
end

【问题讨论】:

    标签: ruby-on-rails activerecord associations has-many-through has-many


    【解决方案1】:

    之前的解决方案是错误的,我误解了其中一个关系。

    Rails 无法为您提供跨越多态关系的 has_many 方法。原因是实例分布在不同的表中(因为它们可以属于不同的模型,这些模型可能在同一个表上,也可能不在同一个表上)。所以,如果你跨越了belongs_to多态关系,你必须提供source_type。

    话虽如此,假设您可以像这样在 Investor 中使用继承:

    class Investor < ActiveRecord::Base
      has_many :investments
    end
    
    class VcFirm < Investor
    end
    
    class Angel < Investor
    end
    

    您可以从投资中删除多态选项:

    class Investment < ActiveRecord::Base
      belongs_to :investor
      belongs_to :company
    
      .........
    end
    

    您将能够跨越关系并根据条件对其进行范围:

    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
    

    【讨论】:

    • 不起作用。这是错误:ActiveRecord::HasManyThroughAssociationPolymorphicSourceError: 不能有 has_many :through 关联 'Company#investors' 在多态对象 'Investor#investor' 上没有 'source_type'。尝试将 'source_type: "Investor"' 添加到 'has_many :through' 定义中。
    • 嗯...那么我不得不将人员和金融机构存储在同一张表中,这感觉不对。
    • 我告诉过你有哪些选择。你不能使用关系意图,因为它不能工作。如果您只想检索两者的列表,请在 Company "def Investors; vc_firms + angels; end" 上创建一个方法。
    【解决方案2】:

    我在Company 类中添加了一个方法,该方法通过加入投资表来获取公司的所有投资者:

    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 看起来非常有助于阅读 :source:source_type

    希望对你有帮助!

    【讨论】:

      猜你喜欢
      • 2013-07-08
      • 2011-06-30
      • 2011-01-08
      • 1970-01-01
      • 2011-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多