When using shallow routes, different routes require different form_for arguments

别等时光非礼了梦想. 提交于 2019-11-28 17:46:46

If the first object in the array you pass the form builder is nil, Rails will POST to the second object only. For this reason simply don't set your @customer object in your controller's edit action. If you need access to the customer object, call it through @note.

If you're using the same partial for new and edit, you'll want to set @note.customer in the controller's new action (@customer won't be set when editing).

I think this is how the Rails team intended it to work.

I'd like to offer a slight modification to James' solution:

# app/helpers/application_helper.rb
def shallow_args(parent, child)
  child.try(:new_record?) ? [parent, child] : child
end

Instead of relying on the controller action being called "new" -- though it likely will be 95% of the time -- this just checks if the child is a new record.

Here's what I came up with:

app/helpers/application_helper.rb

module ApplicationHelper

  # Public: Pick the correct arguments for form_for when shallow routes 
  # are used.
  #
  # parent - The Resource that has_* child
  # child - The Resource that belongs_to parent.
  def shallow_args(parent, child)
    params[:action] == 'new' ? [parent, child] : child
  end

end

app/views/notes/_form.html.erb

<%= simple_form_for shallow_args(@customer, @note), html: { class: 'form-vertical'} do |f| %>
  <%= f.input :content %>

  <%= f.button :submit %>
<% end -%>

I don't know that it's the best solution, but it seems to work alright.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!