0

2 日経っても、この問題を自分で解決できませんでした。それはかなり単純なはずですが、何かが欠けています。Posts と Authors を使用して簡単なブログを作成しています。作成者にはブール値の admin 列があります。

現在エラーが発生している行は、投稿に編集ボタンを表示する権限を確認する場所です。現在のエラーは次のとおりです。

投稿の 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

2つのこと。

current_userまず、コントローラに cancan が依存するメソッドを用意する必要があります。持っていない場合は、

  • current_userメソッドへのエイリアスcurrent_whateverまたは
  • のような能力を手動でインスタンス化し、ビューでその生成された能力であなたの@ability = Ability.new(current_whatever)を呼び出します(のように)。can?@ability.can? :edit, @post

次に、 4 行目と 5 行目の両方でAbility使用していますが、メソッドcurrent_authorに a がありません。しかし、あなたは持っています。アビリティのイニシャライザに使用できる/与えられたオブジェクトがない場合は、代わりに永続化されていない作成者を使用します (AuthorAbility が返されるか、アビリティで引数として取得される場合を除き、AuthorAbility ではありません)。このようなもの:current_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

これが初めての場合は、認証ジェムを確認することをお勧めします。Devise もこれを紹介し、authlogic はハウツーとサンプルアプリケーションでこれを説明しています。認証を最初から行っている場合は、セッションに基づいてユーザーを返すだけです。


edit 2.実際に何をしているのかを理解する必要がありますが、現時点ではそうではありません。あなたはここで少し混乱しています;-)

問題 1:現在の作成者/ログインしているユーザー (アビリティでもフォールバック ユーザーでも他の何かでもない)current_userを返す必要があるか、または作成者がログインしていない場合。たとえば、ビューで行うことができます。は明らかに間違っています。cancan のメソッドはオブジェクトにのみ適用でき、 には適用できないため、アビリティ クラスからのフォールバックはアビリティ クラスにとどまる必要があります。したがって、作成者がログインしていなくても (その場合は が返されます)、自分の能力で、オブジェクトがあることを確認します。nil<% if current_user %>@current_ability ||= Author.new(current_author)nilauthor ||= Author.newcurrent_authornil

問題 2:アプリケーション コントローラーにメソッドhelper_method :current_authorがないため、実際には何もしません。current_authorをどうにかして定義する必要がありますcurrent_author

問題 3: あなたの見解では、間違っcan?たインスタンスを呼び出しています。の方法です。したがって、 @my_ability が eg のインスタンスである場所を使用する必要があります。これは、複数の機能を使用したり、何かをカスタマイズしたりする必要がある場合に使用されますが、ここではそうではありません。レシーバーなしで直接使用してください ( など)。Authorcan?Ability@my_ability.can?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、有効なユーザーが返され (ただし、データベースに少なくとも 1 つは保存されている必要があります)、能力の問題を整理できます。能力が機能する場合は、認証を実装します。初心者として、私は authlogic に固執するか、またはdeviseを使用ます。

于 2013-02-01T13:00:11.067 に答える