2

我正在编写一个模型实例方法,如果它存在则应该找到一个 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
4

1 回答 1

2

ActiveRecord 关系有一个鲜为人知的功能,允许您从它们创建一个实例:

User.where(name: 'John').new #=> <User @name="John">

结合它,find_or_create你就在路上:

Cart.order('created_at DESC').find_or_create_by_purchased_at(nil)

每次调用cartRails 都会运行一个查询,但是它非常高效,因为它会命中在请求结束时过期的查询缓存。假设您没有在调用此方法之间清除所有购物车,那么您应该没问题。

于 2012-06-10T15:17:35.033 回答