2017-11-17 20 views
0

저는 레일스에 새롭다. 그리고 레일즈 5를 사용하여 Devise와 Pundit의 보석을 사용하는 간단한 용어집 앱을 만들고있다. Devise로 Admin 모델을 생성했습니다. 로그인해야하는 유일한 역할입니다. 관리자로 로그인하지 않으면 Pundit을 설치하여 "편집", "삭제"및 "새로 만들기"버튼을 숨길 수있는 정책을 만들었습니다. Glossary App Index레일 : 관리자로 로그인하지 않는 한 "편집"과 "파괴"숨기기

'수정'및 '삭제'버튼을 숨기려면 아래 정책 코드를 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

내가 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에서 구현 제안을 시도했습니다

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 

terms_policy.rb 및 기타 소스의 겉 핥기. 이것들은 모두 훌륭한 리소스라고 확신하지만,이 단계에서는 필자의 프로젝트와 레일스에 친숙한 수준을 목표로 좀 더 필요한 것이 있습니다.

제가 제공 할 수있는 다른 것을 알려주세요. 당신의 도움을 주셔서 감사합니다!

+0

[docs] (https://github.com/plataformatec/devise#controller-filters-and-helpers)에 따라'current_admin'을 사용해야한다고 생각합니다. _ 귀하의 개발 모델이 User가 아닌 다른 것으로 대체되면 "_user"와 "_yourmodel"_ – inye

+0

감사합니다. 나는 당신이 application_controller.rb를 참조하고 있다고 생각합니다. 그래서 "_user"를 "_admin"으로 바꿉니다. 지금 얻고있는 오류는 "# 에 대한 정의되지 않은 메소드'set_current_admin '입니다. set_current_user" 내 terms_controller에서이 메소드를 정의하는 방법을 모르겠습니다. 만약 내가 추측한다면 그것은 개인적인 방법이 될 것입니다 : def set_current_admin end –

+0

'aplication_controller.rb'에'set_current_user'를 정의하면 이름을 바꿔야한다고 생각합니다. – inye

답변

0

안녕하세요 당신은 당신이 할 수 =>

def ensure_admin 
    if current_user.nil? || current_user.is_at_least?(:manager) == false 
     flash[:notice] = I18n.t('must_be_admin') 
     redirect_to root_path 
     return true 
    end 
    false 
    end 

는 희망 방법

컨트롤러의 일부

before_action :ensure_admin, except: [:show, :edit, :update] 
    before_action :ensure_admin_or_user, only: [:edit, :update, :account] 

를 추가 할 수 있습니다!

+0

요르단에 감사드립니다. before_actions를 추가하고 제안 된 방법대로 ensure_admin 메소드를 정의했으며 'current_admin'이 정의되지 않은 오류가 발생했습니다. 그래서 나는 _empty_ 'set_current_admin'메소드를 application_controller에서 terms_controller.rb로 가져 왔고 아무 효과가없는 것으로 보인다. –

+0

시도해보십시오 => current_user.admin 대신 'current_admin? 예 => current_user.admin == true? 다른 일을하십시오. –

0

전문가는 사용자 레코드를 얻기 위해 컨트롤러의 current_user을 찾습니다. pundit_user 방법으로 configure 할 수 있습니다. application_controller.rb에 덮어 쓰면 관리자 레코드가 반환됩니다. 추가 역할 (관리자가 아닌 사용자)를 추가하고자하는 경우 가치가 무엇인지에 대한

def pundit_user 
    Admin.find_however_you're_doing_that 
end 

, 당신은 아마 이것에 대해 고통스러운 방법을 것입니다. 속성으로 정의 된 역할이있는 단일 Devise 모델이 필요할 수 있습니다.

+0

Daniel에게 감사드립니다. 그건 의미가 있으며, 당신이 제안한 것처럼'application_controller.rb'를 편집했습니다. 여전히 같은 오류가 발생합니다. 분명히 난 정말 레일 * 기침 * 여기에서, 그래서 당신이 제공하는이 정보를 사용하여 새 응용 프로그램을 만드는 것이 청소기 쉽게 문제를 해결할 것입니다보고 있어요. 사용자 역할에 관해서는 좋은 지적입니다. –