【问题标题】:Rails 3 Conditions on Eager Loaded AssociationRails 3 急切加载关联的条件
【发布时间】:2011-02-03 23:31:40
【问题描述】:

我在使用 Rails 3 急切加载时在关联表上使用条件时遇到问题。 Rails 在加载原始模型数据时似乎正在应用该条件,因此除非非零数量的子/关联模型与条件匹配,否则它不会加载父模型。这在代码中更容易解释(例如简化):

@post = Post.includes(:comments).where(:comments => { :approved => true }).find(1)

这将生成类似于以下内容的 SQL 查询:

SELECT DISTINCT `posts`.id FROM `posts`
LEFT OUTER JOIN `comments` ON `comments`.`post_id` = `posts`.`id`
WHERE (`comments`.`approved` = 1) AND (`posts`.`id` = '1')
LIMIT 1

如果没有任何满足approved = 1 条件的 cmets,则不会返回任何行,因此根本不会加载 Post。

什么是正确加载帖子和相关 cmets 的正确方法?

更新

我仍然希望听到更好的方法,但现在我正在使用以下方法来解决它(适用于深度嵌套的急切加载):

@post = Post.find(1)
@comments = @post.comments.where(:approved => true).all

# allows deeper/more complex nesting without getting into SQL:
@post = Post.includes(:author => [ :websites, :photo ]).find(1)
@comments = @post.comments.includes(:editor).where(:approved => true).all

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 activerecord eager-loading


    【解决方案1】:

    我猜你正在寻找的是joins 方法,它会让你把你的条件放在连接定义中,而不是在它之外。例如:

    @post = Post.joins("LEFT JOIN comments on posts.id = comments.post_id AND comments.approved = 1").first
    

    不确定条件本身的正确性,但你明白我的意思。

    不幸的是,如果您传递数组/哈希,您必须使用那个丑陋的字符串,因为 joins 正在使用 INNER JOIN。

    还有更多about joins at rails guides

    【讨论】:

    • 这对我来说真的不起作用,因为我实际上做了不止一个级别的急切加载。使用连接时,这会变得相当冗长。我现在通过第二次调用来获取嵌套数据(如 cmets)来避免这个问题。
    【解决方案2】:

    更新this post on includes vs eager_load vs preload 中可能有一些智慧。

    我仍然希望听到更好的方法,但现在我正在使用以下方法来解决它(与使用 joins 不同,使用深度嵌套的渴望加载):

    @post = Post.find(1)
    @comments = @post.comments.where(:approved => true).all
    
    # allows deeper/more complex nesting without getting into SQL:
    @post = Post.includes(:author => [ :websites, :photo ]).find(1)
    @comments = @post.comments.includes(:editor).where(:approved => true).all
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多