我正在编写一个模型实例方法,该方法应该找到AR关联(如果存在),或者如果不存在则创建它。我怎么能这样做,以便在第一次找到后,不再查询数据库?我在下面有这个方法的两个版本但都有缺点。
此方法每次执行查询效率低下。
def cart
carts.order('created_at desc').where(:purchased_at => nil).first || carts.create
end
此方法只进行一次db查找,但在cart.destroy之类的内容后不同步。
def cart
@cart_ || @cart_ = carts.order('created_at desc').where(:purchased_at => nil).first || @cart_ = carts.create
end
答案 0 :(得分:2)
ActiveRecord Relations有一个鲜为人知的功能,允许您从中创建实例:
User.where(name: 'John').new #=> <User @name="John">
将其与find_or_create
相结合,即将开始:
Cart.order('created_at DESC').find_or_create_by_purchased_at(nil)
每次调用cart
Rails都会运行一个查询,然而它非常高效,因为它会触及在请求结束时到期的查询缓存。假设你没有清除这种方法的调用之间的所有推车,你应该没事。