Rails包括范围

Mon*_*nja 28 activerecord scope ruby-on-rails rails-activerecord

我有一个名为Author的模型.一位作者有很多文章.文章有一个名为.published的范围,其中:where(已发布:true).

我想加载作者,发表文章.我试过了:

Author.includes(:articles.published).find(params[:author_id])
Run Code Online (Sandbox Code Playgroud)

但这会引发错误:未定义的方法'已发布'.任何的想法?

小智 40

我认为最好的解决方案是:

Author.includes(:articles).where(:articles=>{published: true}).find(params[:author_id])
Run Code Online (Sandbox Code Playgroud)

或者您可以创建范围:

class Author < ActiveRecord::Base 
    scope :with_published_articles, -> { includes(:articles).where(articles: { published: true}) }
end
Run Code Online (Sandbox Code Playgroud)

然后:

Author.with_published_articles.find(params[:author_id].to_s)
Run Code Online (Sandbox Code Playgroud)


Man*_*ijn 19

我会像这样在被Author调用上指定一个范围with_published_articles:

scope :with_published_articles, -> { joins(:articles).merge(Article.published) }
Run Code Online (Sandbox Code Playgroud)

这将解决您的问题,以便在未来的行为和将来更改的情况下指定where(active: true)您的Author模型.publishedArticle

所以现在你可以打电话:

Author.with_published_articles.find(params[:author_id])
Run Code Online (Sandbox Code Playgroud)

  • 这是最好的答案,因为它没有将作者与文章的“已发布”含义的内部实现结合起来 (2认同)

小智 5

试试这个代码:

Author
  .includes(:articles).where(published: true).references(:articles)
  .find(params[:author_id])
Run Code Online (Sandbox Code Playgroud)

在这里您可以找到有关上述示例的更多信息: includes api doc


小智 5

使用:

class Articles < ActiveRecord::Base 
    scope :published, -> { where(articles: {published: true}) }
end
Run Code Online (Sandbox Code Playgroud)

在 Autor 上定义范围

class Author < ActiveRecord::Base 
    scope :with_published_articles, -> { joins(:articles).merge(Articles.published) }
end
Run Code Online (Sandbox Code Playgroud)

或者

Author.joins(:articles).merge(Articles.published).find(params[:author_id])
Run Code Online (Sandbox Code Playgroud)