Rails:一个表单中的多提交按钮

kin*_*pyo 59 forms action ruby-on-rails

假设我有一个文章模型,在文章"新"视图中我有两个按钮,"发布"和"保存草稿".

我的问题是如何知道在控制器中单击了哪个按钮.

我已经有了解决方案,但我认为必须有更好的方法.我目前在视图中使用的是:

<div class="actions">
  <%= f.submit "Publish" %>
  <%= f.submit "Save Draft", :name => "commit" %>
</div>
Run Code Online (Sandbox Code Playgroud)

所以在控制器中,我可以使用params [:commit]字符串来处理该操作.

def create
  @article = Article.new(params[:article])
  if params[:commit] == "Publish"
    @article.status = 'publish'
    // detail omitted
  end

  @article.save
end
Run Code Online (Sandbox Code Playgroud)

但我认为使用视图相关字符串并不好.你能告诉我另一种方法吗?

更新:由于这些按钮的形式相同,所以它们都会进入"创建"动作,这对我来说没问题.我想要的是在创建操作中处理它,例如给Article模型一个'status'列并保持'public'或'draft'.

Joh*_*ley 64

Railscast第38集介绍了这一点.使用params哈希来检测单击哪个按钮是正确的方法:

视图:

<%= submit_tag 'Create' %>
<%= submit_tag 'Create and Add Another', name: 'create_and_add' %>
Run Code Online (Sandbox Code Playgroud)

控制器:

if params[:create_and_add]
  # Redirect to new form, for example.

else
  # Redirect to show the newly created record, for example.
end
Run Code Online (Sandbox Code Playgroud)


sil*_*hil 7

我们在rails中使用了高级约束来解决.

我们的想法是拥有相同的路径(因此具有相同的命名路由和操作),但约束路由到不同的操作.

resources :plan do
  post :save, constraints: CommitParamRouting.new("Propose"), action: :propose
  post :save, constraints: CommitParamRouting.new("Finalize"), action: :finalize
end
Run Code Online (Sandbox Code Playgroud)

CommitParamRouting是一个简单的类,有一个方法matches?,如果commit参数匹配给定的实例attr,则返回true.值.

这可用作gem commit_param_matching.


Pet*_*kou 6

它也可以在form_for帮助器上完成,就像这样

 <%= f.submit "Publish",name: "publish", class: "tiny button radius success" %>
 <%= f.submit 'Mark as Draft', name: "draft", class: "tiny button radius " %>
Run Code Online (Sandbox Code Playgroud)

并且控制器上的逻辑是相同的

   if params[:publish]
      // your code
   elsif params[:draft]
      // your code
   end
Run Code Online (Sandbox Code Playgroud)