Ruby on Rails 5中如何复用form_for分部视图处理新建/编辑并传路由参数
在Rails 5中用同一个form_for分部视图处理新建/编辑并传递account_id参数
刚好做过类似的场景,在Rails 5里要实现同一个form_for分部视图处理新建和编辑操作,还得带上account_id这个路由参数,其实跟着Rails的约定来就很简单,给你几种靠谱的实现方式:
第一步:控制器里做好前置准备
不管是新建还是编辑动作,都要先获取对应的@account实例,同时让@note和@account关联起来(如果模型有关联的话,推荐这么做,更符合Rails最佳实践):
# app/controllers/notes_controller.rb class NotesController < ApplicationController def new @account = Account.find(params[:account_id]) @note = @account.notes.new # 利用关联新建note,自动关联account_id end def edit @account = Account.find(params[:account_id]) @note = @account.notes.find(params[:id]) # 通过account关联查找note,更安全 end # 其他动作(create/update/destroy)也建议用@account.notes的方式操作 end
第二步:编写通用的form_for分部视图
Rails的form_for支持数组参数来处理嵌套路由,这是最优雅的方式,完全不用手动区分新建和编辑场景:
假设你的分部视图是app/views/notes/_form.html.erb,内容如下:
<%= form_for [@account, @note] do |f| %> <!-- 这里放你的表单字段,示例: --> <div class="field"> <%= f.label :title %> <%= f.text_field :title, class: 'form-control' %> </div> <div class="field"> <%= f.label :content %> <%= f.text_area :content, class: 'form-control' %> </div> <div class="actions"> <%= f.submit class: 'btn btn-primary' %> </div> <% end %>
原理说明:
Rails会自动判断@note的状态:
- 如果是
new动作里的未保存记录,form_for会生成POST请求到account_notes_path(@account),对应路由/:account_id/notes - 如果是
edit动作里的已存在记录,form_for会生成PATCH请求到account_note_path(@account, @note),对应路由/:account_id/notes/:id
完全匹配你配置的路由规则,还自动帮你带上了account_id参数,省心又规范。
可选:如果没有模型关联的情况
要是你的Note和Account没有建立ActiveRecord关联,只是单纯路由嵌套,也可以手动指定url和请求方法,但这种方式不如上面的优雅,仅作参考:
<%= form_for @note, url: @note.new_record? ? account_notes_path(params[:account_id]) : account_note_path(params[:account_id], @note), method: @note.new_record? ? :post : :patch do |f| %> <!-- 表单字段同上 --> <% end %>
第三步:在新建/编辑页面渲染分部
最后在new.html.erb和edit.html.erb里渲染这个分部就行:
# app/views/notes/new.html.erb <h1>新建笔记(账户:<%= @account.name %>)</h1> <%= render 'form' %>
# app/views/notes/edit.html.erb <h1>编辑笔记(账户:<%= @account.name %>)</h1> <%= render 'form' %>
如果你的分部需要接收局部变量(比如不想依赖全局的@account和@note),也可以传参渲染:
# new.html.erb里改成 <%= render 'form', account: @account, note: @note %> # 分部里改成 <%= form_for [account, note] do |f| %> <!-- 字段内容 --> <% end %>
这样就完美实现了同一个分部视图处理新建和编辑操作,还自动传递了account_id参数,完全符合你的需求~
内容的提问来源于stack exchange,提问作者chrickso
相关产品推荐
相关产品推荐

