[英]Ruby on rails AASM Change transition on button click
我的问题很简单:如何在单击按钮时更改aasm
转换? 我应该把什么放在我的视野里?
我有两个按钮: Approve
和Reject
。 我的状态是这样的:
aasm :column => 'state' do
state :pending, :initial => true
state :approved
state :rejected
event :approve do
transitions :to => :approved, :from => [:pending]
end
event :reject do
transitions :to => :rejected, :from => [:pending]
end
end
更新:我的参数是这些:
{"utf8"=>"✓", "_method"=>"put", "authenticity_token"...", "commit"=>"APP", "id"=>"65"}
。
这就是我从视图访问操作的方式:
= form_for([:admin, shop], method: :put, data: { confirm: "You sure?" }) do |f|
= f.submit "Approve", :controller => :shops, :action => :approve
我的控制器代码:
def approve
@shop = Shop.find(params[:id])
@shop.approve!
end
路线:
namespace :admin do
get "shops/:id/approve" => "shops#approve"
正如Srikanth
所提到的,您需要将您的请求发送给您的控制器,但是,我建议您使用button_to
,而不是直接使用form
,如下所示:
<%= button_to "Approve", admin_shops_approve_path(shop.id), method: :put %>
<%= button_to "Disapprove", admin_shops_disapprove_path(shop.id), method: :put %>
这将向您的控制器发送请求。 您似乎已经这样做了,但为了澄清,您需要使用以下内容:
#config/routes.rb
namespace :admin do
resources :shops do
put :approve #-> domain.com/admin/shops/:id/approve
put :disapprove #-> domain.com/admin/shops/:id/disapprove
end
end
#app/controllers/admin/shops_controller.rb
class Admin::ShopsController < ApplicationController
before_action, :set_shop
def approve
@shop.approve!
end
def disapprove
@shop.disapprove!
end
private
def set_shop
@shop = Shop.find params[:id]
end
end
这将为您提供一种将所需数据发送到表单的有效方式,从而触发AASM
流程。
Aasm 通过向模型添加状态、转换和事件来工作。
您无法直接从视图访问模型。 相反,您可以在控制器中创建可以绑定按钮的相应操作。
请注意,aasm 事件具有逻辑,即您可以转换到哪个事件等。您可以执行所有这些验证并从您的控制器操作中提供适当的响应消息。
编辑:
这是我将如何做的想法:
FooController.rb:
class FooController < ApplicationController
def approve
foo = Foo.find(params[:id])
foo.approve!
end
def reject
foo = Foo.find(params[:id])
foo.reject!
end
end
路线.rb:
get "foo/:id/approve" => "foo#approve"
get "foo/:id/reject" => "foo#reject"
用你的模型替换Foo
!
我有同样的问题。 我是这样解决的:
模型
class Call < ActiveRecord::Base
include AASM
aasm_column :status
aasm do
state :start, :initial => true
state :in_progress
state :finished
state :archived
event :run do
transitions :from => [:start, :finished, :archived], :to => :in_progress
end
event :stop do
transitions :from => :in_progress, :to => :finished
end
event :resolve do
transitions :from => [:in_progress, :finished], :to => :archived
end
end
end
控制器
class CallsController < ApplicationController
before_action :set_call, only: [:run, :stop, :resolve]
def run
redirect_to calls_path if @call.run!
end
def stop
redirect_to calls_path if @call.stop!
end
def resolve
redirect_to calls_path if @call.resolve!
end
private
def set_call
@call = Call.find(params[:id])
end
end
路线routes.rb
resources :calls do
member do
put :run
put :stop
put :resolve
end
end
视图调用/index.html.erb
<table>
<thead>
<tr>
<th>Name</th>
<th>Status</th>
<th>Start call</th>
<th>Stop call</th>
<th>Resolve call</th>
</tr>
</thead>
<tbody>
<% @calls.each do |call| %>
<tr>
<td><%= call.name %></td>
<td><%= call.status %></td>
<td><%= link_to "Start", run_call_path(call) , method: :put %></td>
<td><%= link_to "Stop", stop_call_path(call), method: :put %></td>
<td><%= link_to "Resolve", resolve_call_path(call), method: :put %></td>
</tr>
<% end %>
</tbody>
</table>
我当前的项目需要创建 AASM 选择器,这取决于 CanCan 和当前事件的许可。
如果有人正在寻找此功能,欢迎您使用此要点:https ://gist.github.com/alexey/446c6c4ce2a5af0f4fb6851e6d6d514e
它的创建速度很快,所以请原谅一些丑陋的方法(很快就会将其重写为更好的格式)
您也欢迎阅读本文以了解复杂的集成
您还可以在模型中添加回调,例如
before_update { |order| order.log_status_change if order.aasm_state_changed? }
*filed_name_<_已更改?>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.