0

我正在制作一个添加海报的应用程序,它是适度的。我有两个角色:管理员和用户。用户可以创建海报并可以更新它。当用户完成后,他按下“推送”按钮并推送发布者进行审核,因此管理员可以接受或拒绝。我想在“推送”操作之后执行此操作,当用户的海报已饱和“推送”时,用户无法更改海报。这是我的一些文件:

能力.rb

class Ability
include CanCan::Ability

def initialize(user)
  user ||= User.new # guest user (not logged in)
  if user.has_role? :admin
    can :manage, :all
    cannot :create, Poster
  end
  can :read, Poster

  if user.has_role? :user
    can :create, Poster
    can :update, Poster, user_id: user.id
    cannot :update, Poster, state: "pushed"
    can :destroy, Poster, user_id: user.id

  end

海报.rb

class Poster < ActiveRecord::Base
  has_many :poster_images, dependent: :destroy
  accepts_nested_attributes_for :poster_images, allow_destroy: true
  belongs_to :type
  belongs_to :user
  default_scope -> { order('created_at DESC') }

  validates :title, :body, :publish_date, :user_id, :type_id, presence: true


  state_machine initial: :draft do

    event :push do
      transition draft: :pushed
    end

    event :reject do
      transition pushed: :rejected
    end

    event :accept do
      transition pushed: :accepted
    end

    event :publish do
      transition accepted: :published
    end

    event :archive do
      transition published: :archived
    end
  end
end

posters_controller.rb

class PostersController < ApplicationController
  before_action :authenticate_user!, except: [:index, :show]
  authorize_resource except: [:push, :my_posters]
  load_resource except: :create
  # GET /posters
  # GET /posters.json
  def index
    @posters = Poster.paginate(page: params[:page], per_page: 10)
  end

  # GET /posters/1
  # GET /posters/1.json
  def show; end

  def admin_show
    @posters = Poster.paginate(page: params[:page], per_page: 10)
  end

  def my_posters
    @posters = Poster.paginate(page: params[:page], per_page: 10)
  end

  # GET /posters/new
  def new; end

  # GET /posters/1/edit
  def edit

  end

  # POST /posters
  # POST /posters.json
  def create
    @poster = Poster.new(poster_params)
    @poster.user_id = current_user.id
    @poster.publish_date = DateTime.now
    respond_to do |format|
      if @poster.save
        format.html { redirect_to @poster, notice: 'Poster was successfully created.' }
      else
        format.html { render action: 'new' }
      end
    end
  end

  # PATCH/PUT /posters/1
  # PATCH/PUT /posters/1.json
  def update
    respond_to do |format|
      if @poster.update(poster_params)
        format.html { redirect_to @poster, notice: 'Poster was successfully updated.' }
      else
        format.html { render action: 'edit' }
      end
    end
  end

  # DELETE /posters/1
  # DELETE /posters/1.json
  def destroy
    @poster.destroy
    respond_to do |format|
      format.html { redirect_to posters_url }
    end
  end

  [:accept, :reject, :publish].each do |method_name|
    define_method method_name do
      @poster.send(method_name)
      flash[:notice] = "#{method_name.capitalize} was successful."
      redirect_to posters_path
   end
  end

  [:push].each do |method_name|
    define_method method_name do
      @poster.send(method_name)
      flash[:notice] = "#{method_name.capitalize} was successful."
      redirect_to posters_path
    end
  end

  private
    # Never trust parameters from the scary internet, only allow the white list through.
    def poster_params
      params.require(:poster).permit(:title, :body, :type_id, :type_name,
      poster_images_attributes: [:image, :id] )
    end  
end

据我了解,我写了 cannot :update, Poster, state: "pushed"(在我的迁移中,我的状态为字符串),它应该可以工作,但是用户在按下按钮后仍然可以更改海报,尽管海报发生了变化这是要推动的状态。我做错了什么?

4

1 回答 1

0

我发现了愚蠢的错误。一切正常,除了控制器。我不得不这样做

authorize_resource except: [:push, :my_posters, :edit]

和这个

def edit
  authorize! :update, @poster
end

一切正常。

于 2013-10-22T07:49:42.040 回答