2016-09-22 46 views
0

用戶模型有一個屬性:admin,可以是true或false。我想進行驗證,只有擁有admin = true的用戶才能發佈文章或查看視圖中的「新文章」按鈕。我該怎麼做才能讓只有管理員的用戶才能發表文章?

我現在用的色器件寶石

控制器(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 

模型(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 

模型(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 

方案:

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 

視圖/篇(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 /> 

提前感謝所有出色的人在這裏願意伸出援助之手。

+0

您可以更新您的視圖文件還 –

+0

是的,我添加視圖文件。 –

+1

爲了獲得更好的用戶角色支持,您可以使用Pundit或CanCanCan寶石。 – Aleksey

回答

3

您可以在應用程序控制器

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

添加過濾器方法和Atricles控制器或其中要求

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

而在視圖中的任何其他地方使用此,檢查用戶是否是admin

<% if current_user.admin %> 
    # new/edit/delete links 
<% end %> 

儘管未在視圖中顯示鏈接解決了問題,但它還是在服務器端最好有適當的授權邏輯。

+0

非常感謝!這工作完美。 –

-1

要顯示New Article鏈接到唯一的管理員。將條件添加到您的link_to標記。這隻會隱藏鏈接。

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

假設您希望管理員用戶只創建新文章。然後,您需要在應用程序中實施授權。嘗試cancancan寶石

對於控制器

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 

在視圖中docsvideo

+0

只是隱藏鏈接並不妨礙用戶在瀏覽器的地址欄中輸入「users/new」或「users/123/edit」的URL。 – spickermann

+0

我知道這就是我提到這兩種情況的原因。 :) –

+0

「可以發佈文章或查看問題中的」視圖中的「新文章」按鈕「來回答這個問題。 –

0

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

Santhosh的回答是一個很好的答案。 –

相關問題