2017-05-12 7 views
1

私はcancancan宝石における役割の能力(レール5、postgresの、工夫を)宣言した:cancancan行ベースのフィルタ

can [:update, :show, :destroy, :index], SalesDatum do |datum| 
    datum.try(:user_id) == user.id #the ids just access the id's from the user object that is passed into can can and from the table 
end 

SalesDatumuser_idフィールドがあります。

私は例えばuser_idにログインしただけshow SalesDatumことができるので、これは、ショーのアクションで動作します:user_idのログインがSALES_DATA

上のuser_idと一致するため

http://localhost:8080/projects/19/sales_data/961 が正しく認証され

http://localhost:8080/projects/19/sales_data/800 ログインしたuser_idがsales_dataのuser_idと一致しないため、正しく認証されません

しかし、私がgeに行くとtインデックスアクション: http://localhost:8080/projects/19/sales_data @sales_data変数からのすべての売上データが表示されます。だから、それはdata.id 800と961

販売データコントローラを示すだろう。

load_and_authorize_resource 
def index 
    @sales_data = SalesDatum.where(project_id:params[:project_id]) 
end 

にはどうすればindexアクションが唯一の関連のuser_idでデータを表示するのですか? cancanはフィルタリングすることはできませんuser_idによると?

+0

コントローラのクエリを 'SalesDatum.where(project_id:params [:project_id])。(user_id:' current_user.id') 'に編集することはできますが、これは本当に貧弱な認証方法のようです。 – HoosierCoder

+0

これは私がCanCanCanを放棄してPunditを捨てた理由です。信じられないほどシンプルなDSLは、認証スコープの定義や何か重要な処理をうまくやっていません。 – max

答えて

1

ルールをハッシュ構文で定義する必要があります。

can [:update, :show, :destroy, :index], SalesDatum, user_id: user.id 

あなたもそのためeditアクションとを定義することもできます。

に簡略化することができ
can [:edit, :update, :show, :destroy, :index], SalesDatum, user_id: user.id 

:SalesDatumがある場合

can :manage, SalesDatum, user_id: user.id 

belongs_to :userあなたも書くことができます定義されました:

can :manage, SalesDatum, user: user 
+0

これは素晴らしいことですが、ブロック構文でこれを行う良い方法はありませんか? – HoosierCoder

+1

ブロック構文は、コレクションではなくインスタンスでのみ機能するため、常に最後の選択肢にする必要があります。コレクションの場合、ハッシュ構文を使用する必要があります。 – coorasse

関連する問題