私はRailsの新機能です。Rails 5を使用してDeviseとPunditの宝石を使った簡単な用語集アプリを作成しています。私はDeviseでAdminモデルを生成しました。それはログインする必要がある唯一の役割です。管理者としてログインしていない限り、「Edit」、「Destroy」、「New」ボタンを非表示にするポリシーを作成するためにPunditをインストールしました。 Glossary App IndexRails:管理者としてログインしていない限り、「編集」と「破棄」を非表示にします。
「編集」を隠し、ボタンを「破壊」するために私のindex.html.erbファイルに以下のポリシーコードを追加した後、私は「未定義のメソッド 『CURRENT_USER』」なエラーになっています。
<tbody>
<% @terms.each do |term| %>
<tr>
<td><%= term.name %></td>
<td><%= term.category %></td>
<td><%= term.definition %></td>
<td><%= link_to 'Show', term, class: 'btn btn-mini' %></td>
<td>
<% if policy(@term).edit? %>
<%= link_to 'Edit', edit_term_path(term), class: 'btn btn-mini' %>
<% end %>
</td>
<td>
<% if policy(@term).destroy? %>
<%= link_to 'Destroy', term, method: :delete, class: 'btn btn-mini', data: { confirm: 'Are you sure?' } %>
<% end %>
</td>
</tr>
<% end %>
</tbody>
私が考案し、「ユーザー」モデルを生成し、代わりに「管理者」モデルを生成していなかったので、エラーが私の新しいポリシーで単語「ユーザー」に言及していたことを論理的に思えました。だから私は私のapplication_policy.rbとterms_policy.rbで "user"を "admin"に置き換えました。明らかに、私はまだそれを得ているので、このエラーで「ユーザー」が何を意味するのか理解していません。
私はあなたがそう、ここで、参照する必要が正確にわからないです、私のモデル、コントローラ、およびポリシー:
application_record.rb
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
end
admin.rb
class Admin < ApplicationRecord
has_many :terms
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :trackable, :timeoutable, :lockable
end
term.rb
class Term < ApplicationRecord
belongs_to :admin
def self.search(search)
if search
where(["name LIKE ?","%#{search}%"])
else
all
end
end
end
application_controller.rb
class ApplicationController < ActionController::Base
include Pundit
protect_from_forgery with: :exception
before_action :set_current_user
def set_current_user
Term.current_user = current_user
end
end
terms_controller.rb
class TermsController < ApplicationController
before_action :set_term, only: [:show, :edit, :update, :destroy]
before_action :authenticate_admin!, :only => [:new, :edit, :create, :destroy]
# GET /terms
# GET /terms.json
def index
@terms = Term.search(params[:search])
end
# GET /terms/1
# GET /terms/1.json
def show
end
# GET /terms/new
def new
@term = Term.new
end
# GET /terms/1/edit
def edit
@hide_edit_button = true
end
# POST /terms
# POST /terms.json
def create
@term = Term.new(term_params)
respond_to do |format|
if @term.save
format.html { redirect_to @term, notice: 'Term was successfully created.' }
format.json { render :show, status: :created, location: @term }
else
format.html { render :new }
format.json { render json: @term.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /terms/1
# PATCH/PUT /terms/1.json
def update
respond_to do |format|
if @term.update(term_params)
format.html { redirect_to @term, notice: 'Term was successfully updated.' }
format.json { render :show, status: :ok, location: @term }
else
format.html { render :edit }
format.json { render json: @term.errors, status: :unprocessable_entity }
end
end
end
# DELETE /terms/1
# DELETE /terms/1.json
def destroy
@term.destroy
respond_to do |format|
format.html { redirect_to terms_url, notice: 'Term was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_term
@term = Term.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def term_params
params.require(:term).permit(:name, :category, :definition)
end
def verify_is_admin
(current_admin.nil?) ? redirect_to(root_path) :
(redirect_to(root_path) unless current_admin.admin?)
end
end
application_policy.rb
class ApplicationPolicy
attr_reader :admin, :record
def initialize(admin, record)
@admin = admin
@record = record
end
def index?
false
end
def show?
scope.where(:id => record.id).exists?
end
def create?
false
end
def new?
create?
end
def update?
false
end
def edit?
update?
end
def destroy?
false
end
def scope
Pundit.policy_scope!(admin, record.class)
end
class Scope
attr_reader :admin, :scope
def initialize(admin, scope)
@admin = admin
@scope = scope
end
def resolve
scope
end
end
end
terms_policy.rb
class TermPolicy < ApplicationPolicy
def index?
true
end
def create?
user.present?
end
def update?
return true if user.present?
end
def edit?
user.admin?
end
def destroy?
user.admin?
end
end
私はAccess to current_user from within a model in Ruby on Rails、undefined local variable or method `current_user' using devise & rails 3.2、https://code.tutsplus.com/tutorials/authorization-with-pundit--cms-28202からの提案を実装しようとした、および他のソースの片言てきました。これらはすべて素晴らしいリソースであると確信していますが、この段階では、私のプロジェクトとRailsに精通したレベルのものを少しは必要としています。
他に何ができるのか教えてください。ご協力いただきありがとうございます!
[docs](https://github.com/plataformatec/devise#controller-filters-and-helpers)に基づいて 'current_admin'を使用する必要があると思います。あなたのdeviseモデルがUser以外のものであれば、 "_user"と "_yourmodel" _ – inye
ありがとうございます。私はあなたがapplication_controller.rbを参照していると推測しているので、 "_user"を "_admin"に置き換えました。私が今得ているエラーは、 "定義済みメソッド' set_current_admin 'for#意味ですか?set_current_user " 私のterms_controllerでこのメソッドを定義する方法がわかりません。もし私が推測するなら、それは私的な方法でしょう: def set_current_admin end –
あなたは 'aplication_controller.rb'で' set_current_user'を定義します。私はあなたが名前を変更する必要があると思います – inye