我想在ActiveRecord::Relation
对象中找到特定记录,以便我可以获取该记录的属性。
以下是有效的,但问题是它使用find_by
语句再次访问数据库。它不应该。 rails应该有一种方法可以在ActiveRecord::Relation
对象中找到该对象,而不必再次查询数据库。
#returns an ActiveRecord::Relation object
@blogs = Blog.all
# Search for the blog within that ActiveRecord::Relation object, NOT the database
@blogs.find_by(id: 1).title #do this statement but don't hit the database again
答案 0 :(得分:15)
加载完成后,可以使用常规数组方法。 find
实际上是非常有趣的方法 - 如果指定了block,它将被委托给关系目标:
@blogs.find {|b| b.id == 1}
答案 1 :(得分:12)
当你致电find_by
时,它会打到数据库。
关系对象用于延迟加载db结果。
为all
调用加载后,您可以在生成的数组中进行搜索。
如果你想在ruby过程中查看已经存在于内存中的结果,那么你应该使用find
或detect
(它做同样的事情)来查看数组。我倾向于使用detect
,所以很明显它没有访问数据库:
@blogs.detect { |b| b.id == 1 }
http://ruby-doc.org/core-2.2.0/Enumerable.html#method-i-detect
答案 2 :(得分:1)
您可以像这样扩展定义的关联:
class User < AR
has_many :roles do
def find_for(params)
find { |record| params.all? { |key, val| record[key] == val } }
end
end
end
User.first.roles.find_for(foo: 'bar', baz: 'word') # => return instance of Role if its #foo equal 'bar' and its #baz equal 'word'
答案 3 :(得分:-2)
您始终可以使用where
子句。例如
@blogs.where(id: 1).first.reload
获取(并从数据库重新加载)ID为1的@blog实例。请记住,此查询将快速,高效且安全(如果您要添加params[:id]
而不是硬编码ID。