How to post to a nested resource in Rails? - ruby-on-rails

I have a nested resource in my routes.rb file:
resources :users do
resources :children
end
I have a form at /users/:id/children/new. Form comes up fine and the embedded ruby for the form looks like this:
<%= form_for(#user) do |f| %>
Problem is I want this to submit to /users/:id/children, but it submits to /users. Is there a standard way this should be done in Rails?

The embedded form shold look like this
<%= form_for [#user, Children.new] do |f|%>
<%= f.label :children_attr,.....%>
.
.
see this vedio, it might help.

Related

Re-writing Rails form helper in simple form

Is the following line in Rails Simple form
<% form_for #user :url => {:action => "attempt_login"}, do |f| %>
The same as the following in Rails form helper?
<%= form_tag(:action => 'attempt_login') do %>
If not, can you tell me what it would be? I need to redo some form code and I would like write down the correct syntax before running the app...
For in the case of passing parameters (i.e. :action) the simple form documentation is rather ambiguous.
Thanks!
The form_for is usually used for a specific record in order to update or create it.
Example:
# view in HAML (not ERB)
= form_for #user do |f|
= f.text_field :username
# matched with the routes
resources :users
other example with nested resources:
# routes.rb
resources :users do
resources :posts
end
# view in HAML
= form_for [#user, #post] do |f|
= f.text_field :content
Since you gave a record as an argument to the form_for method, it can "pre-fill" some fields of your record, i.e. if the #user already has a value for username, the field will be populated with that username.
It is true that you can specify an action to the form_for, something like this:
= form_for #user, url: { action: :custom_action } do |f|
The form_tag is used for the "other forms", such as a login form or a specific controller's action to be done.
Example:
# view in HAML
- form_tag action: :login do
= text_field_tag :username
= password_field_tag :password
To conclude, I would (based on my opinion) use the form_for helper if you are actually using a model's instance in the form and trying to modify/create it. So in your case, I would not use the form_for helper but use the form_tag instead (because you want a login form).
I recently migrated my form_tag methods to form_for because form_for was used in a gem that formatted my form using bootstrap. This was for a login form with no model. Here's how I used form_for without a model:
<%= form_for(:login, :action => 'attempt_login') do %>
I assume this works for simple_form as well:
<%= simple_form_for(:login, :action => 'attempt_login') do %>
Instead of using a form_tag, because the gem didn't decorate it, I used a form_for with a :symbol instead of a #model

'no implicit conversion of symbol into Integer' with form_for

I am receiving
no implicit conversion of symbol into Integer
with the following code:
<%= form_for #question, admin_questions_path do |f| %>
<%= f.label :question %>
<%= f.text_area :question %>
<% end %>
But when I change the form_for method as follows; the form renders correctly.
<%= form_for [:admin, #question] do |f| %>
What is the difference between the code? If the incorrect code is routing to the create method of the Admin::QuestionsController with the path admin_questions_path why does it not work? I am new to rails and namespacing, so I may be missing something completely obvious.
Edit:
The questions controller is namespaced under admin.
namespace :admin do
resources :questions, only: [:index, :new, :create]
end
The first example should be syntactic sugar for writing the following (if i'm not mistaken):
form_for [#question, admin_questions_path] do |f|
Where you most likely wanted:
form_for #question, url: admin_questions_path do |f|
Your second form uses polymorphic routing to automatically determine the correct route, this is useful if you want to use the same form for editing and creating. The link Arup provided should be helpful about that topic, as is the guide about routing at: http://guides.rubyonrails.org/routing.html

Rails 4 action routes with simple_form and shallow nested resources

resources :users, shallow: true do
resources :shoes
end
This gives me two different routes for create and edit
user_shoes_path
shoes_path
In my shoes _form.html.erb if I leave the form tag :url as default I get a missing routes error when I submit a new or updated shoe.
If I supply the url in the form I can get it to work for either the new or the edit update, but I can't get it to work for both.
This works for the new:
<%= simple_form_for :shoe, url: user_shoes_path do |f| %>
This works for the edit, but will fail once it tries the actual update since it redirects to /:param_id:
<%= simple_form_for :shoe, url: shoes_path(#shoe) do |f| %>
How can I make it work for both? Thanks.
You should use
<% = simple_form_for [#user, #shoe] do |f| %>
and let do simple_form do the work...
This case, if there is a #user, simple form will use it (as for a new), if there isn't (like for an edit), simple form won't use it...

Trouble with Rails ActiveRecord relationships and adding a record for one model within another models view

I put all the code in this gist because I can't get the formatting to work.
https://gist.github.com/anonymous/72e66308c236a0277943
What I am trying to do is to have a form for the prof_comments model on the Professors page.
Whenever I try and submit the form I currently have for the prof_comments model, it tries to post to the current professors show page (/professors/1)
I've been trying to follow the following StackOverflow posts, but no luck yet.
Rails: Show form from different model in a view
Possible to add a form into another models view in rails
Routes.rb
Rails.application.routes.draw do
root :to => "welcome#index"
devise_for :users
resources :users
resources :professors
resources :prof_comments
resources :classes
resources :class_comments
end
I'm not sure about the approach you were trying but this will do exactly what you are trying to do: have the professor's comments appear under it's show page.
You can nest prof_comments under professors
your routs will look like this:
resources :professors do
resources :prof_comments, shallow: true
end
prof_comments controller:
def create
#professor = Professor.find(params[:id]) #this pulls specific professor by :id
#prof_comment = #professor.prof_comments.create(prof_comment_params)
redirect_to professor_path(#professor) # this will rout you to professor's show page once the comment is created.
end
end
in app/views/professors/show.html
h2>Add a comment:</h2>
<%= form_for([#professor, #professor.prof_comments.build]) do |f| %>
<%= f.label :commenter %><br> #commenter with the actual attribute_name
<%= f.text_field :commenter %> #commenter with the actual attribute_name
<%= f.label :body %><br> #body should be replaced with your actual attribute_name
<%= f.text_area :body %> #body should be replaced with your actual attribute_name
<%= f.submit %>
<% end %>
these comments will appear under the professor show view. the comments are nested under it. Treat the professor's controller as usual. you'll be using to create the comments using prof_comments controller.
You have to use
form_for #prof_comment
with # not :

Binding multiple objects to a Rails form

I'm following this tutorial - http://tutorials.jumpstartlab.com/projects/blogger.html#i2:-adding-comments. It is building a sample blog app and so far has an Article model and is adding a Comment model. An Article has_many Comments.
They want to be able to create the comment using a form on the articles page:
<h3>Post a Comment</h3>
<%= form_for [ #article, #comment ] do |f| %>
<p>
<%= f.label :author_name %><br/>
<%= f.text_field :author_name %>
</p>
<p>
<%= f.label :body %><br/>
<%= f.text_area :body %>
</p>
<p>
<%= f.submit 'Submit' %>
</p>
<% end %>
I don't understand how this form works though. It binds two objects to the form, and it says that it'll submit to article_comments_path, which will POST to comments#create.
How does this work? How does it know what to do when it has two objects? Does the order of the objects in the array matter? Can you have more than two objects?
you are probably going to use nested resources:
resources :articles do
resources :comments
end
[ #article, #comment ] is an array which will build a nested route. Like:
/articles/1/comments
article_comments_path maps to the index action (GET) and to create action(POST)
dorake routes to see what i'm talking about:
article_comments_path GET /articles/:article_id/comments(.:format) comments#index
POST /articles/:article_id/comments(.:format) comments#create
So essentially, you use [ #article, #comment ] when you have nested resources to create routes helpers. the order of the objects matter as it is article_comments_path and NOT comment_articles_path.
whether you can bind more than 2 objects to the form, it depends, I think, on how deeply nested are your resources
UPDATE:
you are using a form. and forms are for either to create or update objects depending on whether the object exists or not. The submit button will trigger that. This article sums it pretty good
"When the user clicks submit on a form, Rails invokes either the create (for a new record) or update (for an existing record) action in the associated controller. Forms are, by default, submitted with an HTTP POST command, and all the information that was entered in the form is provided in a hash called params, which is available to the controller."

Resources