Why is my nested resource form trying to use a non-existent path method when I've already set the URL? - ruby-on-rails

I have the following routes defined in my application:
resources :users do
resources :data_sets
end
The form data_sets/new is accessed from the following link:
<%= link_to "New Data Set", new_user_data_set_path(user) %>
The form is defined as such:
<%= form_with model: #data_set, url: [#data_set.author, #data_set] do |form| %>
<!-- form contents... -->
<% end %>
The form gives the following error upon loading:
Showing .../app/views/data_sets/new.html.erb where line #1 raised:
undefined method `data_sets_path' for #<#<Class:0x00007ffd2d1dcf90>:0x00007ffd292a63d0>
The following parameters were passed:
{ "user_id" => "1" }
Similar questions posted here seem to indicate that defining the URL typically solves problems with nested resource forms, but as you can see I already have. What else is going on here?

The form_with helper build the nested url from the array you passed. But in case of new record, #data_set.author returns nil and the form tries to reach data_sets_path which does not exist.
If your form is just for the "new" action you can write:
<%= form_with model: #data_set, url: [:user, #data_set] do |form| %>
If you share the form between "new" and "edit", you can write a condition like that:
<%= form_with model: #data_set, url: [(#data_set.new_record? ? :user : #data_set.author), #data_set] do |form| %>

Related

Same form partial, params present on create, but absent on update

I have a form partial that I reuse for create and update actions. On hitting the create action, I get the expected params hash but the same doesn't happen on update. Here's my form partial.
<%= form_for :track, url: url, method: method do |f| %>
...
<% end %>
Which I then call from a view:
<%= render partial: 'form', locals: { url: tracks_path, method: :post } %>
The corresponding route:
post '/:user/:playlist/tracks' => 'tracks#create', as: :tracks
And the controller action:
def create
render plain: params[:track].inspect
end
On submit, I receive all the fields of that form alright as a nested hash of params[:track]. Oddly, I don't get what I'm expecting for the update action:
# view
<%= render partial: 'form', locals: { url: update_track_path, method: :patch } %>
# route
patch '/:user/:playlist/:track' => 'tracks#update', as: :update_track
# controller
def update
render plain: params[:track].inspect
end
I'm expecting params[:track] in this case to also be a nested hash but its content is instead a string. And this string happens to be the value of :track in /:user/:playlist/:track.
I'm confused. How do I get back the nested hash?
I think there is a naming conflict. params[:track] is being defined in two ways:
the route /:user/:playlist/:track defines params[:track] as that segment of the url
your form defines params[:track] as a the hash of values
To work around this, change the param name in your URL. For example, change the url pattern to /:user/:playlist/:track_name, then access the URL param as params[:track_name].
That way, there won't be a conflict between URL params and form params!

Undefined method error when using simple_form (newbie)

I've got the following simple_form:
= simple_form_for instance do |f|
= f.input :update_resolution, collection: 1..10
= f.button :submit
It throws the error:
undefined method `update_resolution' for #<Instance:0x007f0c07329640>
In instances_controller.rb I have:
def update_resolution
render nothing: true, status: 200, content_type: 'text/html'
end
And I'm not 100% sure what's best to put in routes.rb.
Goal: I'm trying make an auto-submitting dropdown to allow the user to run update_resolution with certain params.
Questions:
Why does it throw this error & how can I fix it?
What is the preferred routes.rb strategy?
This can be achieved with a model less simple_form. Look at the following code:
<%= simple_form_for :user, url: users_path do |f| %>
<%= f.input :name, as: :string %>
...
<% end %>
url: users_path can be changed to the action you want it to post to. In your case update_resolution_instance_path The action will take the params being passed to it and do whatever it needs to do.
I am using something similar to be able to take data from fields and then send an email to the user entered email address.

Using a partial from another view while that model's routes are nested in the current view Rails 3

I've got two models/views, User and PersonalInfo and I'm trying to call the _form.html.erb partial in the 'user#show' action, but I'm getting an error:
No route matches {:controller=>"personal_info"}
I suspect the issue is that my PersonalInfo routes are nested within the User routes and Rails isn't using the right one, but I don't know how to make it use the right one. Here's the line that's calling the form:
app/views/users/show.html.erb:
<%= render :partial => "/personal_info/form", :locals => {personal_info: #personal_info } %>
app/views/personal_info/_form.html.erb:
<%= form_for #personal_info, url: user_personal_info_index_path, html: { method: :post } do |f| %>
routes.rb:
resources :users do
resources :personal_info
end
Do I either have to declare something in the personal_info controller or specify the app to use the users/:user_id/personal_info route?
I was able to get this resolved by changing:
<%= form_for #personal_info, url: user_personal_info_index_path, html: { method: :post } do |f| %>
to:
<%= form_for #personal_info, url: new_user_personal_info_index_path, html: { method: :post } do |f| %>

Rails 4 error: can't write unknown attribute `html'

Running into an error trying to set up a basic Rails 4 app for learning purposes, so bear with me! I am trying to create an app to create and display custom web forms. I have a Form model, which has many Fields. I'm at the point where I'm trying to get the view working that will allow me to create a new Field record attached to a specific Form:
class Form < ActiveRecord::Base
has_many :fields
end
class Field < ActiveRecord::Base
belongs_to :form
end
On my Field index view, which I believe I have set up to correctly to only show the Fields of a specific form (via a url like /forms/1/fields), I have a link as such:
<%= link_to 'New Field', new_form_field_path(#form) %>
The fields/new.html.erb file has this:
<h1>New field</h1>
<%= render :partial => 'form', :form => #form, :field => #field %>
And the fields/_form.html.erb starts like this:
<%= form_for(#form, #field) do |f| %>
The fields_controller.rb has this method defined:
def new
#form = Form.find(params[:form_id]) #unsure if this is necessary/correct, but its presence doesn't effect the error i'm getting
#field = Field.new
end
A Form with id 1 has already been created. It looks like /forms/1/fields comes up ok. But when I click the "New Field" link, which takes me to /forms/1/fields/new, I get this error:
Showing /home/moskie/Projects/FormBuilder/app/views/fields/_form.html.erb where line #1 raised:
can't write unknown attribute `html'
Extracted source (around line #1):
<%= form_for(#form, #field) do |f| %>
<% if #field.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#field.errors.count, "error") %> prohibited this field from being saved:</h2>
Trace of template inclusion: app/views/fields/new.html.erb
Rails.root: /home/moskie/Projects/FormBuilder
Application Trace | Framework Trace | Full Trace
app/views/fields/_form.html.erb:1:in `_app_views_fields__form_html_erb___1866877160086017450_70350628427620'
app/views/fields/new.html.erb:3:in `_app_views_fields_new_html_erb___1515443138224133845_70350627074400'
Request
Parameters:
{"form_id"=>"1"}
I'm pretty confused by what this error is telling me, so I'm having trouble figuring out what I've done wrong here. Can anyone help me out? Thanks.
Got it. The call to form_for in the _form.html.erb Field partial view needed square brackets, instead of the parenthesis. The method wants an array of the two objects as its first parameter in this case, not to have the two objects passed in separately:
<%= form_for [#form, #field] do |f| %>

Undefined method 'model_name' in index.html.erb

I have a Dashboard controller and in the index method i have #message = Message.new( Message is my model )...In my index.html.erb i have a form
<%= form_for #message do |f| %>
<%= f.text_field :message %><br>
<%= f.submit "Send" %>
<% end %>
and i get an error at first line of the form "undefined method `messages_path'"...
I don't have a new method in my controller
Pls help
Do you have a resources :messages route in config/routes.rb? The error is happening when Rails tries to create the form's submission route from the class of the argument to form_for
that error occurs when you did not specified respective routes in routes.rb file so just add
resources :messages
or if you want explicit route for some certain method add that in route file

Resources