2016-09-22 1 views
0

Das Benutzermodell hat ein Attribut: admin, das wahr oder falsch sein kann. Ich möchte eine Validierung vornehmen, damit nur Benutzer mit dem Attribut admin = true Artikel posten oder die Schaltfläche "Neuer Artikel" in der Ansicht sehen können.Wie kann ich es so machen, dass nur Benutzer, die Admins sind, Artikel posten können?

Ich bin mit dem devise gem

Controller (articles_controller.rb):

class ArticlesController < ApplicationController 
    before_action :set_article, only: [:show, :edit, :update, :destroy] 
    before_action :authenticate_user! 

    # GET /articles 
    # GET /articles.json 
    def index 
    @articles = Article.paginate(page: params[:page], per_page: 4) 
    end 

    # GET /articles/1 
    # GET /articles/1.json 
    def show 
    end 

    # GET /articles/new 
    def new 
    @article = current_user.articles.build 
    end 

    # GET /articles/1/edit 
    def edit 
    end 

    # POST /articles 
    # POST /articles.json 
    def create 
    @article = current_user.articles.build(article_params) 

    respond_to do |format| 
     if @article.save 
     format.html { redirect_to @article, notice: 'Article was successfully created.' } 
     format.json { render :show, status: :created, location: @article } 
     else 
     format.html { render :new } 
     format.json { render json: @article.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

    # PATCH/PUT /articles/1 
    # PATCH/PUT /articles/1.json 
    def update 
    respond_to do |format| 
     if @article.update(article_params) 
     format.html { redirect_to @article, notice: 'Article was successfully updated.' } 
     format.json { render :show, status: :ok, location: @article } 
     else 
     format.html { render :edit } 
     format.json { render json: @article.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

    # DELETE /articles/1 
    # DELETE /articles/1.json 
    def destroy 
    @article.destroy 
    respond_to do |format| 
     format.html { redirect_to articles_url, notice: 'Article was successfully destroyed.' } 
     format.json { head :no_content } 
    end 
    end 

    private 
    # Use callbacks to share common setup or constraints between actions. 
    def set_article 
     @article = Article.find(params[:id]) 
    end 

    # Never trust parameters from the scary internet, only allow the white list through. 
    def article_params 
     params.require(:article).permit(:title, :body) 
    end 
end 

Model (article.rb):

class Article < ActiveRecord::Base 

    belongs_to :user 
    has_many :comments 


    validates :title, length: { minimum: 5 } 
    validates :title, uniqueness: true, uniqueness: { message: "This article title has already been posted."} 
    validates :body, length: { minimum: 15 } 
end 

Model (user.rb):

class User < ActiveRecord::Base 
    # Include default devise modules. Others available are: 
    # :confirmable, :lockable, :timeoutable and :omniauthable 
    devise :database_authenticatable, :registerable, 
     :recoverable, :rememberable, :trackable, :validatable 
    validates_uniqueness_of :username 
    has_many :articles 
    has_many :comments 

end 

Schema:

ActiveRecord::Schema.define(version: 20160320222854) do 

    create_table "articles", force: :cascade do |t| 
    t.string "title" 
    t.text  "body" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
    t.integer "user_id" 
    end 

    create_table "comments", force: :cascade do |t| 
    t.text  "body" 
    t.integer "user_id" 
    t.integer "article_id" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
    end 

    add_index "comments", ["article_id"], name: "index_comments_on_article_id" 
    add_index "comments", ["user_id"], name: "index_comments_on_user_id" 

    create_table "contacts", force: :cascade do |t| 
    t.string "name" 
    t.string "email" 
    t.text  "message" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

    create_table "users", force: :cascade do |t| 
    t.string "username",    default: "", null: false 
    t.string "email",     default: "", null: false 
    t.string "encrypted_password",  default: "", null: false 
    t.string "reset_password_token" 
    t.datetime "reset_password_sent_at" 
    t.datetime "remember_created_at" 
    t.integer "sign_in_count",   default: 0,  null: false 
    t.datetime "current_sign_in_at" 
    t.datetime "last_sign_in_at" 
    t.string "current_sign_in_ip" 
    t.string "last_sign_in_ip" 
    t.string "confirmation_token" 
    t.datetime "confirmed_at" 
    t.datetime "confirmation_sent_at" 
    t.string "unconfirmed_email" 
    t.datetime "created_at",        null: false 
    t.datetime "updated_at",        null: false 
    t.boolean "admin",     default: false 
    t.string "firstname" 
    t.string "lastname" 
    end 

    add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true 
    add_index "users", ["email"], name: "index_users_on_email", unique: true 
    add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true 

end 

Ansicht/Artikel (index.html.erb):

<div class="row"> 
    <!-- Blog article Content Column --> 
    <div class="col-lg-8"> 
<% @articles.each do |article| %> 
     <!-- Blog article --> 

     <!-- Title --> 
     <h4 style="font-size: 45.5px;"><%= link_to article.title, article %></h4> 
         <!-- Date/Time --> 
     <p><span class="glyphicon glyphicon-time"></span> 
     <%= time_ago_in_words(article.created_at) %> 
     </p> 


     <!-- Author --> 
     <p> 
      Article By:<strong> <%= article.user.username %></strong> 
     </p> 

     <hr> 

     <% end %> 

<%= link_to "New article", new_article_path, class: "btn btn-default btn-xs" %> 

    </div> 



<!-- paginate --> 

<%= will_paginate @articles %> 

<br /> 

Vielen Dank im Voraus für alle wunderbare Menschen hier bereit, eine helfende Hand zu bieten.

+0

Können Sie die Ansicht Datei auch –

+0

aktualisieren Ja, fügte ich die View-Datei . –

+1

Für eine bessere Unterstützung von Benutzerrollen können Sie Pundit- oder CanCanCan-Edelsteine ​​verwenden. – Aleksey

Antwort

3

Sie können

def admin_access 
    render(text: 'Unauthorised') and return unless current_user.admin 
end 

eine Filtermethode in Application Controller hinzufügen und diese in Atricles Controller oder an jedem anderen Ort, wo es erforderlich ist,

before_filter :admin_access, only: [:new, :create, :edit, :update, :destroy] 

Und in den Ansichten, ob Benutzer admin

Obwohl, zeigt nicht die Verbindung in der Ansicht löst das Problem, es ich Es ist immer besser, eine richtige Autorisierungslogik auf der Serverseite zu haben.

+0

Vielen Dank! das hat perfekt funktioniert. –

-1

Um den New Article Link zum einzigen Admin anzuzeigen. Fügen Sie Ihrem Tag link_to einen Zustand hinzu. Dies wird nur die Verbindung verbergen.

Angenommen, Sie möchten, dass Benutzer nur einen neuen Artikel erstellen. Dann müssen Sie die Autorisierung in Ihrer Anwendung implementieren. Versuchen cancancan gem

Für die docs und video

+0

Das Verstecken des Links verhindert nicht, dass der Benutzer die URL 'users/new' oder' user/123/edit' in die Adressleiste des Browsers eingibt. – spickermann

+0

Ich weiß schon, das ist der Grund, warum ich beide Szenarien erwähne. :) –

+0

"kann Artikel posten oder den Button" Neuer Artikel "in der Ansicht" in der Frage sehen, um so zu antworten. –

0

in der Steuerung

def new 
    if current_user.admin 
    @article = current_user.articles.build 
    else 
    redirect_to root_path and return #somewhere you want to redirect 
    end 
end 

in der Ansicht

<% if current_user.admin %> 
    <%= link_to "New article", new_article_path, class: "btn btn-default btn-xs" %> 
<% end %> 
+0

Santhoshs Antwort ist eine gute. –

Verwandte Themen