首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rails-4,对于存在的用户模型属性,CanCan返回nil:NilClass的未定义方法。

Rails-4,对于存在的用户模型属性,CanCan返回nil:NilClass的未定义方法。
EN

Stack Overflow用户
提问于 2013-09-10 20:50:36
回答 1查看 2.4K关注 0票数 1

在我的应用程序中,我使用的是设计和cancan。我的seller:boolean.产品模型有一个belong_to :user用户表有一个列belong_to所以,在我的能力类中,我有这一行product.try(:user).seller,如粘贴在问题中的create类中所示,这一行在ProductsController#create中抛出了NoMethodError,当我试图创建新产品时,未定义的方法‘So :NilClass’。但是在控制器创建动作中,用户对象而不是nil,因为当我在错误后检查日志时,我看到从“用户”选择“user”.*。“id”= 11

另外,在rails控制台中,如果我这样做的话:

代码语言:javascript
复制
   a = Product.find(4)    
   a.user.seller  will return  => true   

我的能力课

代码语言:javascript
复制
 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   

产品总监:

代码语言:javascript
复制
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一起工作,我的应用程序控制器

代码语言:javascript
复制
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的缩短版本。

代码语言:javascript
复制
<% @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 %>

另一个效果是,编辑破坏链接将显示给销售者,以获取不属于他们的产品,除非我注释掉了引起错误的行,即CanCan的能力类中的product.try(:user).seller == true。所以当注释掉的时候,我得到了这个屏幕截图1,里面隐藏着隐藏在产品上的链接,而当没有注释的时候,你会得到屏幕截图2,所有的产品编辑链接都会显示给销售者,即使产品不是他们的。

屏幕截图1与product.try(:user).seller ==真正的CanCan能力类中注释掉,它只显示了属于signed_in卖家的前两个产品的编辑链接

截图2与product.try(:user).seller ==真正的CanCan能力类中完好无损。参见编辑链接正在显示的较低的产品,即,恤,袖口链接,他们不属于signed_in卖家。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-09-10 21:10:21

您的can :manage块定义稍有错误。是块的返回值决定了用户是否具有这种能力。在您的块中,您有两个语句,其中只有第二个语句对用户是否有能力有任何影响。您需要使用&&连接您的语句。

此外,您的错误似乎是当一个产品没有用户时,而不是当当前用户为零时。您也需要在返回try时使用product.try(:user),因为如果没有产品,则为零。

所以,我觉得你的街区需要:

代码语言:javascript
复制
can :manage, Product do | product |
  product.try(:user_id) == user.id &&
  product.try(:user).try(:seller) == true 
end
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18728517

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档