2017-11-17 4 views
0

Ich bin brandneue auf Schienen, und erstelle eine einfache Glossar App mit Rails 5 mit Edelsteine ​​Devise und Pundit. Ich habe ein Admin-Modell mit Devise erstellt. das ist die einzige Rolle, die angemeldet werden muss. Ich habe Pundit installiert, um Richtlinien zu erstellen, die es mir ermöglichen, die Schaltflächen "Bearbeiten", "Löschen" und "Neu" auszublenden, wenn sie nicht als Administrator angemeldet sind. Schienen: Hide "Bearbeiten" und "Destroy", wenn nicht als Admin eingeloggt

Nachdem ich den unten genannten Richtliniencode zu meiner index.html.erb-Datei hinzugefügt habe, um die Schaltflächen 'Bearbeiten' und 'Zerstören' auszublenden, erhalte ich die Fehlermeldung "Undefinierte Methode '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> 

Da ich einen „User“ -Modell mit Devise nicht erzielt wurde, sondern ein „Admin“ Modell stattdessen erzeugt, schien es logisch, dass der Fehler in meinen neuen Richtlinien auf das Wort „user“ bezog. Also habe ich "user" durch "admin" in meiner application_policy.rb und terms_policy.rb ersetzt. Klar verstehe ich nicht was "user" in diesem Fehler bedeutet, da ich es immer noch bekomme.

Ich weiß nicht, was genau Sie sehen müssen, sind so hier meine Modelle, Controller und Politik:

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 

ich Umsetzung Vorschläge von Access to current_user from within a model in Ruby on Rails versucht haben, undefined local variable or method `current_user' using devise & rails 3.2, https://code.tutsplus.com/tutorials/authorization-with-pundit--cms-28202, und ein paar Brocken von anderen Quellen. Ich bin mir sicher, dass dies alles großartige Ressourcen sind, aber in diesem Stadium brauche ich etwas gezielteres für mein Projekt und die Vertrautheit mit Rails.

Lassen Sie mich wissen, was ich sonst noch bieten kann. Danke für Ihre Hilfe!

+0

Ich denke, Sie müssen verwenden 'current_admin' gemäß der [Docs] (https://github.com/plataformatec/devise#controller-filters-and-helpers) _Wenn Ihr Gerät Modell ist etwas anderes als Benutzer, ersetzen "_user" mit "_yourmodel" _ – inye

+0

Danke inye. Ich nehme an, Sie beziehen sich auf die application_controller.rb, also habe ich "_user" durch "_admin" ersetzt. Der Fehler, den ich jetzt bekomme, ist "undefinierte Methode' set_current_admin 'für # Meinst du? Set_current_user " Ich bin mir nicht sicher, wie ich diese Methode in meinem terms_controller definieren kann. Wenn ich raten sollte, wäre das eine private Methode: def set_current_admin Ende –

+0

Sie definieren die 'set_current_user' in der' aplication_controller.rb' Ich denke, Sie müssen den Namen ändern – inye

Antwort

0

Hallo können Sie versuchen, einige

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

in Ihrem Controller

mit method =>

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 

Hopes seine hilft Ihnen hinzuzufügen!

+0

Danke Jordan. Ich habe die before_actions hinzugefügt und die Methode "use_admin" so definiert, wie Sie es vorgeschlagen haben, und sie ist mit einem Fehler zurückgekehrt, der besagt, dass "current_admin" nicht definiert ist. Also habe ich meine Methode _empty_ 'set_current_admin' vom application_controller auf die terms_controller.rb gezogen, und es scheint keine Wirkung zu haben. –

+0

Haben Sie versucht => current_user.admin anstelle von 'current_admin? ex => aktuelle_benutzer.admin == true? etwas tun: etwas anderes tun –

0

Pundit sucht in Ihrem Controller nach current_user, um den Benutzerdatensatz zu erhalten. Sie können configure dies mit der pundit_user Methode. Überschreibe es in application_controller.rb, um deinen Admin-Datensatz zurückzugeben.

def pundit_user 
    Admin.find_however_you're_doing_that 
end 

Für was es wert ist, sind Sie wahrscheinlich eine schmerzhafte Art und Weise darüber gehen, wenn Sie beabsichtigen, weitere Rollen (Nicht-Admin-Benutzer) hinzuzufügen. Wahrscheinlich möchten Sie ein einzelnes Devise-Modell mit Rollen, die als Attribut definiert sind.

+0

Danke Daniel. Das macht Sinn, und ich habe den 'application_controller.rb' so bearbeitet, wie Sie es vorgeschlagen haben. Ich bekomme immer noch den gleichen Fehler. Anscheinend bin ich wirklich von den Schienen * hust * hier gegangen, also sehe ich, wenn das Erschaffen einer neuen Anwendung mit diesen Informationen, die Sie zur Verfügung gestellt haben, sauberer und einfacher ist, zu behandeln. In Bezug auf Benutzerrollen ist das ein guter Punkt. –

Verwandte Themen