当我在Rails中分配数据库查找实例变量时,为什么以后对该变量的请求也会命中数据库?这可以避免吗?
例如,我有3个模型:User,Resource,Opinion,with 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调用。
答案 0 :(得分: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
命中数据库并查看*指定的列内部。
以前回答的剩余评论
如果此对象需要访问资源模型上的数据,请不要忘记.include()
方法,这将使您不必在路上运行其他查询。
@opinions = current_user.opinions.include(:resources)
请参阅http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations