0

当我将数据库查找分配给 Rails 中的实例变量时,为什么将来对该变量的请求也会访问数据库?这可以避免吗?

例如,我有 3 个模型:User、Resource、Opinion,使用 has_many :through on Opinion

@opinions = current_user.opinions # pulls in all of the user's opinions, which include respective resource ids
1、直接调用resource_id并没有命中数据库:
@opinions.each do |opinion|
  opinion.resource_id  # does not hit the database (as expected)
end
2. 执行查询确实会命中数据库(即使已分配变量):
@opinions.find_by_resource_id(1) # DOES hit the database

为什么#2 会命中数据库?有没有办法在不访问数据库的情况下执行相同的查找?

该信息已包含在 @opinions 变量中,因此似乎不需要进行 db 调用。

4

1 回答 1

0

如果您不需要@opinions数组中的任何其他内容,我会将您的原始查询范围限定为仅包含具有该内容的意见resource_id

@opinions = current_user.opinions.where("resource_id = ?", resource_id)

如果您已经拥有@opinions并且只想创建一个与特定键/值匹配的新对象数组:

@opinions_with_resource_id = @opinions.select { |opinion| opinion.resource_id == 1234 }

查看this other answer以获得其他解释,或者如果您想将答案拆分为多个数组。

想法

评论你的最后一段代码

像您所说的方法find_by_*是动态查找器,用于method_missing访问数据库并查看 *.

上一个答案的剩余评论

如果此对象需要访问 Resource 模型上的数据,请不要忘记该#includes()方法,这将使您不必在以后运行其他查询。

@opinions = current_user.opinions.includes(:resources)

请参阅http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations

于 2012-09-28T21:26:02.390 回答