Rails 3使用nested_has_many_through的复杂关联

Aja*_*nda 7 scope named-scope ruby-on-rails associations ruby-on-rails-3

我一直在努力开发一个基于电影的rails应用程序,它支持多个地区(好莱坞,宝莱坞等).我将多个区域称为应用程序中的语言.

每种语言都有自己的数据集,即英语中包含与好莱坞相关的所有电影,而语言印地语则包含与宝莱坞相关的所有电影.

语言模型

class Language < ActiveRecord::Base
  has_many :movies
  has_many :cast_and_crews, :through => :movies, :uniq => true
  has_many :celebrities, :through => :cast_and_crews, :uniq => true

  # FIXME: Articles for celebrities and movies 
  has_many :article_associations, :through => :celebrities
  has_many :articles, :through => :article_associations, :uniq => true
end
Run Code Online (Sandbox Code Playgroud)

这里的电影和名人都有使用article_association类的文章.

电影模型

class Movie < ActiveRecord::Base
  belongs_to :language
  has_many :cast_and_crews
  has_many :celebrities, :through => :cast_and_crews
  has_many :article_associations
  has_many :articles, :through => :article_associations, :uniq => true
end
Run Code Online (Sandbox Code Playgroud)

名人模特

class Celebrity < ActiveRecord::Base
  has_many :cast_and_crews
  has_many :movies, :through => :cast_and_crews, :uniq => true
  has_many :article_associations
  has_many :articles, :through => :article_associations, :uniq => true
end

class ArticleAssociation < ActiveRecord::Base
  belongs_to :article
  belongs_to :celebrity
  belongs_to :movie
end
Run Code Online (Sandbox Code Playgroud)

这就是我的文章模型的定义方式

class Article < ActiveRecord::Base
  has_many :article_associations
  has_many :celebrities, :through => :article_associations
  has_many :movies, :through => :article_associations
end
Run Code Online (Sandbox Code Playgroud)

我想要实现的是language.article应该返回所有与名人和电影相关的文章.

我不使用SQL的原因是find_by_sql不支持ActiveRelation,我将无法使用has_scope功能.

我正在使用nested_has_many_through,has_scope和inherited_resources gems

任何帮助都将非常感谢.

Aja*_*nda 0

好的,这就是我解决这个问题的方法。

在我的 Article 类中添加了以下范围

def self.region(region_id)
  joins(<<-eos
    INNER JOIN
    (
      SELECT DISTINCT aa.article_id
      FROM regions r
           LEFT JOIN movies m on m.region_id = r.id
           LEFT JOIN cast_and_crews cc on cc.movie_id = m.id
           LEFT JOIN celebrities c on c.id = cc.celebrity_id
           LEFT JOIN events e on e.region_id = r.id
           LEFT JOIN article_associations aa on (aa.event_id = e.id or aa.movie_id = m.id or aa.celebrity_id = c.id)
      WHERE r.id = #{region_id}
    ) aa
  eos
  ).where("aa.article_id = articles.id")
end
Run Code Online (Sandbox Code Playgroud)

这给了我一个 ActiveRecord::Relation 实例,我期望它检索电影、名人或事件的所有记录。

感谢所有帮助过我的人。

如果您有任何改进意见,请评论。非常感谢。