最終更新: 2013 年 8 月 29 日 18:54 EST
次のモジュールを定義して、モデルに含めました。ユーザーに役割を与えるために roify gem を使用しています。
module Permissions::Offer
extend ActiveSupport::Concern
included do
# `user` is a context of security
protect do |user, offer|
# Admins can retrieve anything
if user.has_role? :administrator
scope { all }
# ... and view, create, update, or destroy anything
can :view
can :create
can :update
can :destroy
elsif user.present?
# Allow to read any field
can :view
can :create
# Checks offered_by_id keeping possible nil in mind
# Allow sellers to modify/delete their own offers
if offer.try(:offered_by_id) == user.id
can :update
can :destroy
end
else
# Guests can't read the text
cannot :view
end
end
end
end
私が経験しているのは、次のことを行うときです...
respond_with Offer.restrict!(current_user)
返されるすべてのオファーについてロール テーブルを照会します。オファーのリストを要求するときに、この要求を繰り返し行わないようにする方法はありますか? データベースへのヒットを回避するために応答をキャッシュできると確信していますが、キャッシュにもヒットしない方がよいでしょう。
Rails コンソールを開いて次の操作を行うと、同じ結果が得られます。
current_user = User.first
Offer.restrict!(current_user).to_a
Bullet gem をインストールして、N+1 クエリと見なされるかどうかを確認しましたが、検出されません。オファーの新しいインスタンスが作成されるたびに含まれているものが呼び出され、この呼び出しを開始して権限を確認するためだと思います。これは、rolify がそのユーザー ロール チェックを一定時間キャッシュしないという事実と相まって、これを理想的とは言えません。roify は、キャッシュのクリアに対処することなく、その場でロールを変更できるようにするためにこれを行うと思います。今のところ、これを解決する唯一の方法は、独自のキャッシュを実装することです。