【问题标题】:Rails: Why are has_many relations not saved in the variable/attribute like belongs_to?Rails:为什么has_many关系没有保存在像belongs_to这样的变量/属性中?
【发布时间】:2020-03-26 10:39:26
【问题描述】:

假设我在 Rails 中有以下模型。

class Post < ApplicationRecord
  belongs_to :user
end
class User < ApplicationRecord
  has_many :posts
end

当我将 Post 实例放入变量中并对其调用 user 时,以下 sql 查询运行一次,然后将结果保存/缓存。

post.user
User Load (0.9ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
#<User id: 1 ...>

post.user
#<User id: 1 ...>

etc.

但是,当我使用 user.posts 反过来时,它总是运行查询。

user.posts
Post Load (1.0ms)  SELECT `posts`.* FROM `posts` WHERE `posts`.`user_id` = 1 LIMIT 11

user.posts
Post Load (1.0ms)  SELECT `posts`.* FROM `posts` WHERE `posts`.`user_id` = 1 LIMIT 11

etc.

除非我将其转换为数组,否则它会被保存。

user.posts.to_a 
Post Load (1.0ms)  SELECT `posts`.* FROM `posts` WHERE `posts`.`user_id` = 1 LIMIT 11

user.posts
# No query here.

但是user.posts 仍然会生成一个ActiveRecord::Associations::CollectionProxy 对象,我可以在该对象上调用其他的activerecord 方法。所以这里没有真正的缺点。

为什么会这样?这似乎对 sql 优化产生了不必要的影响。我能想到的一个明显原因是,user.posts 在设置 user 之后创建帖子时会正确更新。但实际上这并没有发生太多 imo,因为变量大多是在连续运行的控制器动作中设置和重置的。现在我知道有一个缓存系统可以在服务器日志中显示 CACHE Post sql,但是当我在模型之间使用 activerecord 对象或更复杂的查询时,我不能真正依赖它。

我在这里错过了一些最佳实践吗?或者一个明显的设置可以解决这个问题?

【问题讨论】:

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


    【解决方案1】:

    您正在 irb 中检查此内容,这就是您看到查询始终在运行的原因。

    如果您要编写,则在控制器或其他类中的实际代码块中

    @users_posts = user.posts
    

    查询不会执行...直到您遍历集合或请求#count

    irb,为了提供帮助,总是立即运行查询

    【讨论】:

      猜你喜欢
      • 2015-11-15
      • 1970-01-01
      • 1970-01-01
      • 2014-10-23
      • 1970-01-01
      • 2015-09-06
      • 1970-01-01
      • 1970-01-01
      • 2015-11-04
      相关资源
      最近更新 更多