Using a singleton nested resource, such as:
map.resources :users do |users|
users.resource :position
end
form_for doesn't work when the nested resource is being
added.
For example, in the controller:
def new
@user = User.find(params[:user_id])
@position = @user.build_position
end
and in the view:
form_for [:user, @member] ...
will throw an exception: undefined method
user_positions_path'
The edit action is identical except the nested resource exists,
so in the controller: @position = @user.position instead of
@user.build_position. Using form_for [:user, @member] in the edit
view creates a form with the correct singular route and put method.
It fails to work only when the nested resource is a new record.
I believe the problem is in the polymorphic_url helper, used by
apply_form_for_options! in form_for. The helper determines
inflection based on new_record? for some reason. If the record is
new the inflection is plural. This obviously fails for new
singleton nested resources. Here is the pertinent section of
polymorphic_url:
inflection =
case
when options[:action].to_s == "new"
args.pop
:singular
when record.respond_to?(:new_record?) && record.new_record?
args.pop
:plural
else
:singular
end
It's possible to work around this using a different form_for
syntax to explicitly set the URL, but this seems like a bug because
the behavior is inconsistent between the new and edit actions.