2

カンカンでスプリーの管理/注文サイトを変更しようとしています。私の店では、製品はさまざまなベンダーから販売されています。登録ユーザーにはがありvendor_id、製品にもがありvendor_idます。注文が行われると、LineItem注文からのaにはが含まれるため、が含まれProductますvendor_id

私が達成したいのは、ユーザーがログインして管理パネルの注文ページにアクセスすると、自分の製品が注文された注文しか表示されないということです。ユーザーは、他のベンダー/ユーザーからの他の注文を見るべきではありません。

私はいくつかの能力を設定することによってCanCanでこれをやろうとしました:

  def initialize(user)
    if user.has_spree_role?("shop_manager") && !user.vendor.nil?
      can :admin, Spree::Order
      can :index, Spree::Order, :line_items => { :product => { :vendor_id => user.vendor_id } }
      can :show, Spree::Order, :line_items => { :product => { :vendor_id => user.vendor_id } }
      can :manage, Spree::LineItem, :product => { :vendor_id => user.vendor_id }
      can :read, Spree::Order
    end
  end

ご覧のとおり、ユーザーはインデックスページのwhereでのみ注文を表示し、whereのみ:line_items => { :product => { :vendor_id => user.vendor_id } }を表示する必要があります。LineItems:product => { :vendor_id => user.vendor_id }

しかし、私が得た振る舞いは、注文のインデックスページを表示する権限がないということであり、すべてLineItemが注文の表示アクションで表示されます。

2番目のタスクでは、ビューを変更することをお勧めします。私はスプリーコアからを変更しようとし_order_details.html.erb、すべてが表示されるループを変更しましたLineItems

<% @order.line_items.accessible_by(@current_ability).each do |item| %>

しかし、これは私にUninitialized constant Product(私はそれがあるべきだと思いますSpree::Product)を与えます。だから、私は何をすべきかわからない、インデックスのために、またはでのショーアクションのためにLineItems。誰かがアイデアを持っていることを願っています。

4

2 に答える 2

1

:read、:show、:indexに同時に制限を設定するのはなぜですか?

:readは、:indexと:show、およびエイリアスされたメソッドを想定しています。

次に、関連する条件に合格した場合は、:joinまたは:includeする必要があります。

def initialize(user)
  if user.has_spree_role?("shop_manager") && !user.vendor.nil?
    can :admin, Spree::Order
    can :read, Spree::Order, Spree::Order.includes(:line_items).where(:line_items => { :product => { :vendor_id => user.vendor_id } })
    can :manage, Spree::LineItem, Spree::LineItem.includes(:product).where(:product => { :vendor_id => user.vendor_id })
  end
end

2番目の問題については、再試行してください。ただし、ActionViewランタイムの前に、コントローラー内の任意の場所でレコードを収集すると、はるかに優れています。とにかくそれははるかに速くなります。

アップデート:

def initialize(user)
  if user.has_spree_role?("shop_manager") && !user.vendor.nil?
    can :admin, Spree::Order
    can :read, Spree::Order, Spree::Order.includes(:line_items).where(:line_items => { :product => { :vendor_id => user.vendor_id } }) do |order|
      order.line_items.includes(:product).exists?(:vendor_id => user.vendor_id)
    end
    can :manage, Spree::LineItem, Spree::LineItem.includes(:product).where(:product => { :vendor_id => user.vendor_id })
  end
end

ブロックを通過するもの。:readを定義すると、最初のAR :: Relationステートメントが:index(リスト)をフィルタリングし、block句が:showをフィルタリングして、ユーザーができるようにしますか?できませんか?

于 2012-12-12T19:40:21.593 に答える
1

を解決するには、またはフィルタの前にオプションUninitialized constant Product issueを追加する必要があります。:classload_resourceload_and_authorized_resource

https://github.com/ryanb/cancan/wiki/authorizing-controller-actions

于 2014-02-04T19:30:17.887 に答える