【问题标题】:Rails includes with scopeRails 包含范围
【发布时间】:2014-11-27 08:47:06
【问题描述】:

我有一个名为 Author 的模型。一个作者有很多文章。 文章有一个名为 .published 的范围,它执行:where(published: true)。

我想加载作者,以及已发表的文章。 我试过了:

Author.includes(:articles.published).find(params[:author_id])

但这会引发错误:未定义的方法“已发布”。 有什么想法吗?

【问题讨论】:

标签: ruby-on-rails activerecord scope rails-activerecord


【解决方案1】:

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

Author.includes(:articles).where(:articles=>{published: true}).find(params[:author_id])

或者你可以创建范围:

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

然后:

Author.with_published_articles.find(params[:author_id].to_s)

【讨论】:

    【解决方案2】:

    我会在 Author 上指定一个名为 with_published_articles 的范围,如下所示:

    scope :with_published_articles, -> { joins(:articles).merge(Article.published) }
    

    这将解决您的问题,同时在您的 Author 模型上指定 where(active: true),以防 publishedArticle 的行为将来发生变化。

    所以现在你可以调用:

    Author.with_published_articles.find(params[:author_id])
    

    【讨论】:

    • 这是最好的答案,因为它没有将作者与文章的“已发布”含义的内部实现结合起来
    • 据我所知joins不会急于加载,所以这仍然会有n+1的问题
    • 这是正确的答案,因为它降低了未来的更改成本(避免代码重复和泄露已发表文章概念的实现细节)。正如 tantrix 所说,它还避免了作者和文章的进一步耦合。
    【解决方案3】:

    试试这个代码:

    Author
      .includes(:articles).where(published: true).references(:articles)
      .find(params[:author_id])
    

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

    【讨论】:

      【解决方案4】:

      使用:

      class Articles < ActiveRecord::Base 
          scope :published, -> { where(articles: {published: true}) }
      end
      

      在 Autor 上定义范围

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

      或者

      Author.joins(:articles).merge(Articles.published).find(params[:author_id])
      

      【讨论】:

        猜你喜欢
        • 2016-04-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-19
        • 1970-01-01
        • 1970-01-01
        • 2020-08-24
        • 2023-04-05
        相关资源
        最近更新 更多