2016-09-22 34 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的回答是一个很好的答案。 –

相关问题