我正在编写一个模型实例方法,该方法应该找到 AR 关联(如果存在),或者创建它(如果不存在)。我怎样才能做到这一点,以便在第一次查找后,不会再次查询数据库?我有下面这个方法的两个版本,但都有缺点。
这种方法每次都会执行一次查询,效率很低。
def cart
carts.order('created_at desc').where(:purchased_at => nil).first || carts.create
end
此方法仅执行一次数据库查找,但在 cart.destroy 之类的事件之后会失去同步。
def cart
@cart_ || @cart_ = carts.order('created_at desc').where(:purchased_at => nil).first || @cart_ = carts.create
end
最佳答案
ActiveRecord 关系有一个鲜为人知的功能,允许您从中创建实例:
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 都会运行一个查询,但是它的性能非常好,因为它会命中查询缓存,该缓存会在请求结束时过期。假设您没有在调用此方法之间清除所有购物车,那么应该没问题。
关于ruby-on-rails - 不在方法内重复数据库调用的最有效方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10969782/