I have a scaffolded view <em>comments/new</em> that lets the user input :body and :lunch_id. When the form opens the URL string is:
<a href="http://localhost:3000/comments/new?lunch_id=1" rel="nofollow">http://localhost:3000/comments/new?lunch_id=1</a>
I am trying to update_attribute lunch_id by reading the url string with the comments_controller create method below:
def create lunch_id = params[:lunch_id] @commenttest = Comment.new(comment_params) @commenttest.update_attribute(:lunch_id, lunch_id) @commenttest.save end
The problem is the params[:lunch_id] always returns a nill. Why won't it read into the URL string?
I've been at it for hours, so any ideas will help
Below is the rake routes from a recreated environment in a hello world app. This only has a few pages but the params[:lunch_id] is still nil:
Prefix Verb URI Pattern Controller#Act > comments GET /comments(.:format) comments#index > POST /comments(.:format) comments#creat > new_comment GET /comments/new(.:format) comments#new > edit_comment GET /comments/:id/edit(.:format) comments#edit > comment GET /comments/:id(.:format) comments#show > PATCH /comments/:id(.:format) comments#updat > PUT /comments/:id(.:format) comments#updat > DELETE /comments/:id(.:format) comments#destr > say_hello GET /say/hello(.:format) say#hello > say_goodbye GET /say/goodbye(.:format) say#goodbyeAnswer1:
I'm guessing you have a form in
new.html.erb and, when you click submit, it posts the info and calls your
create action, and that's when your
The reason this is happening is because the
params hash does not have permanency when you move through actions. Web servers execute one single action basically from scratch every time you make a request from your browser. When you visit
/comments/new?lunch_id=1, you are making a
GET request, which is mapped to your
new action. However, when you submit the form, you are making a
POST request to the
/comments path, therefore calling
create action. But <strong>this is a new request</strong>, with a whole new
params hash, generated from the new request's path <strong>and the data submitted by the form</strong>.
So, the simple way to fix your problem is to add a new field to keep track of your param:
<%= form_for(@comment) do |f| %> <%= hidden_field_tag :lunch_id, params[:lunch_id] %> . . . . <% end %>
<strong>However</strong>, it seems like you are trying to create comments for lunches, and the right way to do it is to use nested attributes:
#/config/routes.rb resources :lunches do resources :comments end
This way, you can get the form for a new comment in
GET /lunches/1/comments/new and point it to
POST /lunches/1/comments, and rails will automatically set the
params[:lunch_id] value without you having to juggle it around anymore.
As pointed out by AbM the params[:lunch_id] create method cannot see the <a href="http://localhost:3000/comments/new?lunch_id=1" rel="nofollow">http://localhost:3000/comments/new?lunch_id=1</a> URL string. The new method, however, can see the URL string.
So, an instance variable should be set in the new method:
def new @comment = Comment.new @lunch_id = params[:lunch_id] end
Then, the form itself, should have a hidden field that points to this variable:
<div class="field"> <%= f.label :lunch_id %><br> <%= f.hidden_field :lunch_id, :value => @lunch_id %> </div>
When the form is submitted with the create method, the hidden field already has the proper lunch_id from the URL string.