如果涉及多态关联,如何创建'has_many through'关联?

时间:2015-12-30 10:55:16

标签: ruby-on-rails ruby associations

我有4个模型:模型1与模型2相关,模型2与模型3相关。模型2和模型3与模型4相关联,具有多态关联。这一切都有效。我在指定模型1和模型4之间的关联时遇到了麻烦,因此它们以两种方式相关:

  1. 模型1 - 模型2 - 模型4
  2. 模型1 - 模型2 - 模型3 - 模型4
  3. 除了模型1和模型4之间的所有关联之外,您将找到所有关联:

    作者模型:

    has_many :books,     dependent: :destroy
    

    书籍型号:

    belongs_to :author
    has_many   :chapters, dependent: :destroy
    has_many   :titles,   as: :titlesource,       # Polymorphic Association
                          dependent: :destroy
    

    章节模型:

    belongs_to :book
    has_many   :titles,   as: :titlesource,       # Polymorphic Association
                          dependent: :destroy
    

    标题模型:

    belongs_to :titlesource, polymorphic: true
    

    问题:假设您拥有上述关联,并希望了解titles所拥有的author,无论它们是书名还是章节标题。我应该将哪些关联扩展到上面的设置? (我假设has_many through

    更新:如果它只是我想要的书名,我希望将has_many :titles, through: :books添加到Author模型中。但事实并非如此。如果我添加该关联,则Author.first.titles会产生错误undefined method 'titles'。我认为这与多态关联和命名有关...?我做错了什么?

    对于章节标题来说,这更加困难。该关联通过Book模型,然后通过Chapter模型,然后到Title模型。如何在作者模型中包含这些标题?我认为它必须是具有以下逻辑的代码(但显然这段代码不正确):

    has_many :titles, through: :books && :books:chapters
    

    更新:给出的两个答案都使用了SQL。这些解决方案是否不会向db发送大量查询,如果经常使用该方法会导致问题?其中一种方法在性能方面优于另一方法吗?

2 个答案:

答案 0 :(得分:3)

如果您要在Author has_many :titles, through: :books上使用关联,只要您在{{titlesource_idtitlesource_type上设置关联1}}模型迁移。

但是,如果你要添加另一个来通过像Title这样的章节来获取标题,它会覆盖第一个标题,它只会获取has_many :titles, through: :chapters的标题。

因此,如果你不介意sql,我建议给你的解决方案是在作者模型中实现这样的方法。

titlesource_type = 'Chapter'

答案 1 :(得分:1)

如果您不需要ActiveRecord方法(例如whereorder),那么这将为您提供一系列标题。

def titles_array  # sacrificing ActiveRecord methods
  books.collect { |b| b.titles + b.chapters.collect { |c| c.titles } }
end

您仍然可以在单个数组元素上使用AR方法,例如titles_array.first.author