2

AR アソシエーションが存在する場合は検索し、存在しない場合は作成するモデル インスタンス メソッドを作成しています。最初の検索の後、データベースが再度クエリされないようにするにはどうすればよいですか? 以下にこの方法の 2 つのバージョンがありますが、どちらにも欠点があります。

このメソッドは毎回クエリを実行するため、非効率的です。

  def cart
    carts.order('created_at desc').where(:purchased_at => nil).first || carts.create
  end

このメソッドは db ルックアップを 1 回だけ実行しますが、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 に答える