【问题标题】:Rails: Nested where clauses in has_many associationRails:在 has_many 关联中嵌套 where 子句
【发布时间】:2016-07-12 17:45:25
【问题描述】:

TLDR:我无法让 where 子句在嵌套(嵌套的 1 或 2 层)has_many 关联中工作

#Author.rb
has_many :posts


#Post.rb
belongs_to :author
has_one :post_setting


#PostSetting.rb
#Has attributes like draft (bool), flagged(bool), etc.

belongs_to :post

现在,如果我尝试在 Author 中创建一个关联,以查找 post_setting.draft = false 的所有帖子,例如,如下所示。

has_many :published_posts,
  -> {
       includes(:post_setting)
       .where(post_setting: {draft: false})
       .distinct
     },
  class_name "Post"

不幸的是,失败并出现以下错误

PG::UndefinedTable: ERROR:  missing FROM-clause entry for table "post_setting"

或者,我也希望能够执行以下操作 -

#Group.rb
has_many :authors
has_many :posts,
  -> {
       includes(:post_setting)
       .where(post_setting: {draft: false})
       .distinct
     },
through: authors

总的来说,我觉得关于 where/joins/includes 如何在关联中工作的规则不是很清楚。在帖子上创建一个范围是否比在作者的has_many 中包含范围更可取?

谢谢!

PS。我正在使用 Rails 4.2.5。

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    为了使您的查询正常工作,您应该使用正确的命名:

    has_many :published_posts,
      -> {
           includes(:post_setting)
           .where(post_settings: {draft: false}) # Note the plural table name
           .distinct
         },
      class_name "Post"
    

    这可能会造成混淆,但通常条件使用基础表名称,而 joinsincludes 使用关联名称。

    如果您有理由限制通过关联可用的数据集以匹配某些条件,请使用父模型上定义的关联条件。

    如果没有这样的原因,并且您希望在过滤关联数据集时保持灵活性,请使用在引用模型上定义的范围。

    【讨论】:

    • 感谢您的快速回答并指出命名。这样做时,我仍然收到以下错误:PG::UndefinedColumn: ERROR: column post_settings.draft does not exist 思考可能出了什么问题?
    • 你能从db/schema.rb这里发布你的post_settings表架构吗?
    • 实际上,您的解决方案有效 - 非常感谢!对于问题的第二部分,您提到使用“参考模型上定义的范围”。然后如何在has_many 关系中使用范围?假设我在Post 上为已发布的帖子定义了一个范围。我现在如何在Group.rbAuthor.rb 中使用它?使用合并? (这性能效率高吗?)
    • 当你链接范围时,如果这就是你所说的,那么就没有合并。查询是延迟构建的,并在应用诸如firstto_a 之类的终止方法时实际执行。您可以在任何模型上拥有任意数量的示波器,并按照您认为合适的方式将它们链接起来,例如Posts.published.recent.by_date 或者你有什么,每个都是一个单独定义的范围。您也可以将其与条件相结合,例如@author.posts.published(这将应用 WHERE 子句)。最终的 SQL 将反映所有组合的范围和条件。
    • 抱歉,我问了两个不同的问题,弄得一团糟。澄清一下:你提到了@author.posts.published。我可以将其写为has_many 关系,同时仍使用posts 上的已发布范围吗?这可能会让我更容易在与authors 的其他关联中使用(如上例中的Group)?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-06
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    相关资源
    最近更新 更多