[英]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' %> <%= 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_user
您current_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.