Rails状态机无法正常工作

时间:2016-02-09 10:14:17

标签: ruby-on-rails state-machine

我正在创建一个博客应用程序,其中用户可以发布并且只能查看他自己的帖子。只有一个管理员可以查看每个帖子并具有接受或拒绝用户发布的功能。例如,当用户将分享他的帖子时发布然后管理员将批准或拒绝该帖子。如果他批准该帖子将在那里如果管理员拒绝该帖子将被删除。我正在使用状态机,但我有一些问题。我已经采取两个按钮批准和拒绝但他们没有工作。
我只是希望当我点击批准按钮时,我的帖子表中有一个列,默认情况下是一个值" pending"因此,它将更改为批准或拒绝我点击的任何按钮....如果拒绝所以应删除帖子
点击批准按钮未定义的方法`permit' for" state_event = approve":String


[post.rb]

class Post < ActiveRecord::Base 
    require 'rubygems'
    require 'state_machine'

    has_many :documents
    has_many :comments, dependent: :destroy
    belongs_to :user

    validates :title, presence: true, length: {in: 5..10}
    validates :body,  presence: true,length: {in: 5..200}

        #:status is the column in posts table
    state_machine :status, :initial => :pending do
        #button name which is approve
        event :approve do
           transition :pending => :approve
        end
        event :decline do
           transition :pending => :decline
        end
    end




    def self.user_post(id)
        role = User.find_role(id)
        if role == 'admin'
            Post.all

        elsif role == 'user'
            Post.where(user_id: id)

        elsif role == 'developer'
            Post.where(user_id: id)
        end             
    end

    def self.icon(extension)
        case extension
        when 'pdf'
                EXTENSION[1]['pdf']
        when 'png' || 'jpg' || 'jpeg'
            EXTENSION[0]['png']
        when 'doc' || 'odt'
            EXTENSION[2]['doc']
        end     

    end



####limit to upload files not more than ######
    def self.upload(files,post_id)  
        files.each do |file|    
        @file_extension=file.content_type.split('/')[1]         

            doc = Document.new(document: file,post_id: post_id )
            #save is a method which will save the content in the database 
            doc.save!
        end
    end
end


[post_controller]

class PostsController < ApplicationController
    before_action :authenticate_user! 

    def index
        @posts = Post.user_post(current_user).order('created_at DESC').paginate(:page => params[:page], :per_page => 5)
    end 

    def new
        @post = Post.new
    end

    def show    
        @post=find_params
    end

    def create
        @post = Post.new(post_params)           
        @post.user = current_user
        if @post.save
            Post.upload(params[:post][:files],@post.id)         
            redirect_to @post
        else
            render 'new'
        end
    end

    def edit
        @post = find_params

    end

    def update
        @post = find_params
        if @post.update(post_params)
            redirect_to @post
        else
            render 'edit'
        end
    end

    def destroy
        @post = find_params
        @post.destroy
        redirect_to posts_path
    end

    private
        def post_params
            p = params.require(:post)
          if current_user.roles=='admin' # or however you check if the user is authorized
            p.permit(:title, :body, :state_event)
          else
            p.permit(:title, :body)
          end


        end

        def find_params
            Post.find(params[:id])
        end

end


[帖/ _form.html.erb]

<%= form_for @post,html: { multipart: true } do |f| %>
    <% if @post.errors.any? %>
        <div id="errors">
            <h2><%= pluralize(@post.errors.count, "error") %> prevented this post from saving:</h2>
            <ul>
                <% @post.errors.full_messages.each do |msg| %>
                    <li><%= msg %></li>
                <% end %>
            </ul>
        </div>
    <% end %>
    <%= f.label :title %><br>
    <%= f.text_field :title %><br>
    <br>
    <%= f.label :body %><br>
    <%= f.text_field :body %><br>

     <br>
     <!-- if you want to upload multiple files at a time -->
    <%= f.label :files %><br>
    <%= f.file_field :files,:multiple => true %><br>

    <br>


    <%= f.submit %>
    <br>

<% end %>
<br>

[帖/ edit.html.erb]

<div id="page_wrapper">
    <h1>Edit Post</h1>

    <%= render 'form' %>
<br>
        <%= form_for @post do %>
            <%= button_to 'Approve', @post, 
      params: { post: { state_event: 'approve' } } ,
      method: :patch 
        %>

        <%= button_to 'Decline', @post, 
      params: { post: {  state_event: 'decline' } } ,
      method: :patch 
        %>
        <% end %>

</div>

2 个答案:

答案 0 :(得分:1)

如果您想更改模型you need to set the state_event property的状态。

<%= button_to 'Approve', @post, 
      params: { post: { state_event: 'approve' } } 
      method: :patch 
%>

<%= button_to 'Decline', @post, 
      params: { post: {  state_event: 'decline' } } 
      method: :patch 
%>

您还需要在强参数列表中添加参数:

def post_params
  p = params.require(:post)
  if current_user.is_admin? # or however you check if the user is authorized
    p.permit(:title, :body, :state_event)
  else
    p.permit(:title, :body)
  end
end

只需使用f.submit "approve",只需更改params哈希中的submit键即可。

答案 1 :(得分:0)

首先:您的按钮批准和拒绝都会触发相同的行为:他们只会使用form_for @posts发送您的表单构建。 我想当你按下其中一个时,你会将POST消息发送到你的应用程序到post_path(@post)。 我给你的建议首先是拆分这个按钮的行为。尝试为按钮添加值,如下所示:

 <%= f.button  :submit , name: "subaction",value: "approve"%>

在你的行动中你应该看到params [:subaction] ==“approve”。