1

アプリでdeviseとcancanを使用しています。私の製品モデルにはbelongs_to :user があり、User テーブルには列Seller :booleanがあります。したがって、私の能力クラスには、質問に貼り付けられた能力クラスに示されているように、 この行product.try(:user).sellerあります。新しい商品を作ってみてください。しかし、コントローラーの create アクションでは、エラーの後にログを調べると、SELECT "users".* FROM "users" WHERE "users"."id" = 11が表示されるため、ユーザー オブジェクトnil ではありません

また、Rails コンソールで次のようにします。

   a = Product.find(4)    
   a.user.seller  will return  => true   

私の能力クラス

 class Ability
   include CanCan::Ability

   def initialize(user)
     user ||= User.new 

     can :manage, Product do | product |
      product.try(:user_id) == user.id
      product.try(:user).seller == true 
     end
   end
 end   

製品コントローラ:

class ProductsController < ApplicationController
  before_filter :authenticate_user!, except: [:index, :show]
  load_and_authorize_resource only: [:create, :edit, :destroy]
  respond_to :html, :json

  def index
    @products = Product.all
    respond_with @products
  end

  def new
    @product = Product.new    
  end

  def create 
    @user = User.find_by(id: current_user.id)
    @product = @user.products.build(product_params)
    @product.save 
  end

end  

CanCan を Rails 4 で動作させるために、私のアプリケーション コントローラーには

class ApplicationController < ActionController::Base
  #temprary work-around for cancan gem to work with rails-4
  #source https://github.com/ryanb/cancan/issues/835#issuecomment-18663815
  before_filter do
    resource = controller_path.singularize.gsub('/', '_').to_sym
    method = "#{resource}_params"
    params[resource] &&= send(method) if respond_to?(method, true)
  end
end

以下のスクリーンショットをわかりやすくするために、products/index.html.erb の短縮版を次に示します。

<% @products.each do |product| %>     
  <% if user_signed_in? %>      
    <% if can? :update, product %>
      <span class="bottomcentre"><%= link_to 'edit', edit_product_path(product), class: "btn btn-primary"  %></span>
    <% end %>

    <% if can? :destroy, product %>
      <span class="bottomright"><%= link_to "Delete", product, data: {confirm: 'Are u sure?'}, method: :delete, class: "btn btn-danger" %></span>
    <% end %>

   <% end %><!-- closes user_signed_in -->

  <% end %>

  <br/>
  <% if user_signed_in? %> 
    <% if can? :create, Product %>
      <%= link_to 'Create a new Product', new_product_path %>
    <% end %>
  <% end %>

追加の効果は、エラーを引き起こしている行をコメントアウトしない限り、販売者のものではない製品の編集リンクと破棄リンクが販売者に表示されることです。前に示したクラス。したがって、コメントアウトすると、このスクリーンショット 1 が表示され、製品が販売者のものではない場合に編集リンクが非表示になります。

スクリーンショット 1 のproduct.try(:user).seller == trueはCanCan Ability Classでコメント アウトされており、signed_in 販売者に属する最初の 2 つの製品のみの 編集リンクが表示されます。ここに画像の説明を入力

スクリーンショット 2 のproduct.try(:user).seller == trueはCanCan アビリティ クラスにそのまま残されています。シャツカフスボタンである下部の製品に表示されている編集リンクを参照してください。これらは signed_in 販売者のものではありません。 ここに画像の説明を入力

4

1 に答える 1