0

两天后,我自己无法解决这个问题。看起来它应该很简单,但我错过了一些东西。我正在使用帖子和作者创建一个简单的博客。作者有一个布尔管理列。

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

帖子中的 NoMethodError#show

显示 .../posts/show.html.erb 其中第 18 行提出:

未定义的方法 `stringify_keys' 用于#

帖子/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

能力.rb

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 文件中。

4

1 回答 1

1

两件事情。

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

  • current_user您的方法的别名current_whatever
  • 手动实例化能力 like@ability = Ability.new(current_whatever)并在您的视图中调用您can?生成的能力(like @ability.can? :edit, @post)。

其次,您在第 4 行和第 5 行都Ability使用了,但是您的方法中没有。不过,你有。如果没有对象可用/没有提供给能力的初始化程序,则您使用非持久作者(而不是 AuthorAbility,除非您的 AuthorAbility 是返回的或在您的能力中作为参数获得)。像这样的东西:current_authorcurrent_authorinitializeauthorAuthorcurrent_userinitialize

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

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


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

问题 1:current_user需要返回当前登录的作者/用户(不是 abilty 或后备用户或其他用户),或者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?where @my_ability 是 eg 的一个实例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要么设计.

于 2013-02-01T13:00:11.067 回答