如何才能使管理员只能发布文章?

时间:2016-09-22 06:32:19

标签: ruby-on-rails ruby devise

用户模型有一个属性:admin,可以是true或false。我想进行验证,因此只有使用admin = true的用户才能发布文章或查看"新文章"视图中的按钮。

我正在使用设计宝石

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

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

view / articles(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 />

感谢所有愿意伸出援助之手的优秀人才。

3 个答案:

答案 0 :(得分:3)

您可以在Application Controller

中添加过滤方法
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 %>

即使没有在视图中显示链接也能解决问题,在服务器端拥有适当的授权逻辑总是更好。

答案 1 :(得分:0)

控制器中的

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
视图中的

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

答案 2 :(得分:-1)

显示唯一管理员的New Article链接。在link_to标记中添加条件。这只会隐藏链接。

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

假设您希望管理员用户仅创建新文章。然后,您需要在应用程序中实现授权。试试cancancan gem

适用于docsvideo