繁体   English   中英

Rails3 / Devise的CanCan方法存在问题

[英]Problems with CanCan Methods with Rails3 / Devise

两天后,我无法自行解决此问题。 看起来应该很简单,但是我缺少了一些东西。 我正在用Posts and Authors创建一个简单的博客。 作者有一个布尔admin列。

现在出现错误的行是我检查权限以在帖子中显示编辑按钮的地方。当前错误是:

Posts#show中的NoMethodError

在第18行出现的位置显示... / posts / show.html.erb:

#的未定义方法`stringify_keys'

posts / show.html.rb

          <% if @author.can? :update, @post %>
          <p><%= link_to 'Edit', edit_post_path(@post), :class => 'btn' %> &nbsp; <%= link_to 'Destroy', @post, confirm: 'Are you sure?', method: :delete %></p>
          <% end %>

application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery  
  rescue_from CanCan::AccessDenied do |exception|
    redirect_to root_url, :alert => exception.message
  end
  helper_method :current_author
  def current_user
    @current_ability ||= Author.new(current_author)
  end
end

能力

class Ability
  include CanCan::Ability
  def initialize(author)
    author ||= Author.new # guest user (not logged in)   
    if author.admin?
      can :manage, :all
    else
      can :read, :all
    end  
  end
end

另外,据我所知,CanCan正确包含在gem文件中。

两件事情。

首先,您需要在控制器中有一个can_can依赖的current_user方法。 如果您没有一个,可以

  • 别名current_usercurrent_whatever方法或
  • 手动实例化诸如@ability = Ability.new(current_whatever)然后打电话给您can? 在您认为的生成能力上(例如@ability.can? :edit, @post )。

其次,您的Ability在第4行和第5行都使用current_author ,但是您的initialize方法中没有current_author 不过,您有author 如果该功能的初始化程序没有可用的Author对象,则使用非持久性作者(而不是AuthorAbility,除非AuthorAbility是current_user返回或在您的功能中进行initialize东西作为参数)。 像这样:

class Ability
  include CanCan::Ability
  def initialize(author)
    author ||= Author.new # guest user (not logged in)
    if author.admin?
      can :manage, :all
    else
      can :read, :all
    end  
  end
end

根据评论进行编辑以使其更简单:

理想情况下,将current_user方法放入应用程序控制器中,并在视图中将其用作帮助程序(因为您可能希望基于登录的用户有条件地在视图中显示/隐藏/更改内容)。

class ApplicationController < ActionController::Base
  helper_method :current_user

  def current_user
    # return the currently logged in user record
  end
end

如果这对您来说是新手,我建议您看一下身份验证宝。 Devise也对此进行了介绍,而authlogic在其使用方法和示例应用程序中对此进行了描述。 如果您要从头开始进行身份验证,则只需根据会话返回用户。


编辑2.您实际上需要了解您的操作,恕我直言,目前情况并非如此。 你在这里有点混乱;-)

问题1: current_user需要返回当前登录的作者/用户 (不是abilty,fallback用户或其他身份),如果没有作者登录,则返回nil 。因此,例如,您可以在视图中执行<% if current_user %> @current_ability ||= Author.new(current_author)是完全错误的。 来自能力类的后退需要保留在能力类中,因为cancan的方法只能应用于对象,而不能应用于nil 因此,如果您具有author ||= Author.new ,即使没有作者登录,也请确保存在一个对象(在这种情况下, current_author返回nil )。

问题2: helper_method :current_author实际上不执行任何操作,因为您的应用程序控制器中没有current_author方法。 您需要以某种方式定义current_author

问题3:在您看来,您在打电话can? 在一个Author实例上,这是错误的。 can? 是一种Ability的方法。 因此,您需要使用@my_ability.can? 其中@my_ability是例如Ability.new(Author.first)的实例。 如果您需要使用多种能力或自定义某些内容,则使用此方法,此处不是这种情况,那么使用can? 直接没有接收者(例如@author.can? )。

为了进行测试,我将创建以下内容:

class ApplicationController < ActionController::Base
  helper_method :current_user # as defined below...

  def current_user
    # Return a static user here, for testing purposes,
    # like @current_user = User.first or Author.first
  end
end

因此,您的current_user返回一个有效用户(不过,我希望您至少需要在数据库中存储一个用户),然后才能解决能力问题。 如果您的能力有效,则可以实施身份验证。 作为一个初学者,我要么坚持authlogic要么设计一个

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM