Pass value from view to controller rails - ruby-on-rails

Background: I have a controller -- Recipes, which generates all the recipes I have in the db and I can click one to see the detail info of the certain recipe. In the certain recipe view, I also pass all the comments this recipe has received. Below the comments info I can just make new comments upon this recipe.
Here is the question: I of course have the recipe id ----- #recipe.id. When I fill all the comment information and click submit button, this form will post to another controller -- Comments. But I just don't know how to pass the recipe id I have in this page to the Comments controller.
Recipe Controller:
def show
#For getting the ingredient info from ingredient set
#ingredientset=IngredientSet.where("recipeid=?",set_recipe.id)
#ingredients = Array.new()
i=0
#ingredientset.each do |set|
#ingredients[i]=Ingredient.find(set.ingredientid)
i+=1
end
Recipe Information View:(I only show the part for making the comment)
<!--for adding a new comment-->
<div id="add_comment">
<%= form_for(#comment) do |f| %>
<% hidden_field .....%>
<!--Here I want to pass the #recipe.id value into the comment controller-->
<!--But I dont know should I use hidden_field or something else-->
<!--I was .net MVC developer, so I only know something like #html.hiddenfor() or #ViewBag.xxx stuff-->
<div class="field">
<%= f.label :comment %><br>
<%= f.text_field :comment %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
</div>
Also I don't know how to even get the value in the Comments controller since I'm totally new in ruby on rails.
Here is the Comments controller:
def create
#comment = Comment.new(params[:comment])
#comment.recipeid = params[:recipeid])
end
Thank you very much!

In your case, it does sound like a hidden_field tag is what you want.
So, in your form, you'd add:
f.hidden_field :recipeid, <value>
Personally, if I use a hidden_field tag, I look for another way to do this, since those tags can easily be modified in the DOM before form submission. I'd look to see if there's a way to do this in your controller itself.

Related

Updating all with a dictionary in Rails

I have a small CMS-like program that has multiple pages that act like blog posts. Each page has content, and a position integer that identifies in what order they will appear on the page.
On my admin side, I have a draggable list of pages that I can reorder similar to how wordpress orders plugins. The page works as functions, and assigns the value of the dragged position to each page correctly. However, since all sortable pages have their own form, I cannot submit them all at once - only one at a time.
As an example, my code looks like this currently:
<div class="sortable">
<% #pages.each do |page| %>
<div class="dragBox">
<%= form_for(page) do |f| %>
<%= f.number_field :position, class: 'inPosition' %>
<% end %>
</div>
<% end %>
</div>
Because I can get every page_id tied to its new position, is it possible to submit those values in a new hash to get updated all at once in the controller? How would I go about doing this? Is there a better or easier way to do this? Thanks.

Rails render not working as expected

Have a show action on a ticket that pulls in a list of comments on the ticket. My goal is to display the list of ticket comments and then above it give the option for someone to add a comments.
This works when the form is below the list of comments, however when i put the above the comments, i get an error in the render of the comments saying that the record has no user id. Almost like the #comments in my ticket controller is somehow getting this new thing added from the form even though it is instantiated before the render of the form.
Here are my partials and controller. The error when the form is displayed first is "unable to find user_id = 0" That is due to the comments.commenter, which looks for the name of the person submitting the comment.
Ticket Controller
def show
#ticket = Ticket.find(params[:id])
#comments = #ticket.comments
end
tickets/show - The form is in here twice, but i only put it in once when trying to get this to work. I want it to work in the top spot.
<div class="widget-content nopadding">
<ul class="new-comment">
<%= render "comments/form" %> --- Does not work here
</ul>
<ul class="recent-comments">
<%= render #comments %>
</ul>
</div>
<%= render "comments/form" %> --- Works here,
comments/form
<%= form_for([#ticket, #ticket.comments.build]) do |f| %>
<div class="field">
<%= f.label :content %><br>
<%= f.text_area :content %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
comments/comment
<li>
<div class="comments">
<span class="user-info"> User: <%= comment.commenter %> </span>
<p>
<strong>Comment:</strong>
PUBLIC: <%= comment.try(:content) %>
</p>
</div>
</li>
Do you have a default set on the comment user_id to 0? What's happening is the form is building a new comment on the ticket. So i think that is getting rendered in the collection partial in addition to what the ticket already had. With the user_id set to zero, the comment.commenter tries to do the where id = 0, and it blows up.
So if you do have a default on that column, remove it. Foreign keys should default to nil.
The #comments is likely lazy loaded, that's why the _comment partial can be effected. #comments was not invoked until you have the second render. To avoid this, you can switch the #comments in the controller to:
#comments = Comment.where(ticket_id: params[:id])
Hope this made sense. Let me know if the default is the case. It's just a hunch :)

Replace one model attribute by another in rails form

I am building a very simple movie review app with Rails, which does not have any authentication system.
The app has:
a User model (id, name, email), which has many Reviews and has many Comments
a Review model (id, title, image, content), which belongs to one User and has many Comments
a Comment model (id, content), which belongs to one User and belongs to one Review
Here is the _form.html.erb file for comments:
<%= bootstrap_form_for(#comment) do |f| %>
<% if #comment.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#comment.errors.count, "error") %> prohibited this comment from being saved:</h2>
<ul>
<% #comment.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.text_field :content %>
</div>
<div class="field">
<%= f.number_field :review_id %>
</div>
<div class="field">
<%= f.number_field :user_id %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
When adding/editing a comment, the user can chose the Review to which the comment will be attributed, thanks to:
<div class="field">
<%= f.number_field :review_id %>
</div>
which lets him chose between review ids.
Instead, I would like the user to be able to select the review title of the review he wants to comment upon.
I tried to modify the review model with a to_param method, but it did not solve the problem and actually created some other bugs in the app.
How can I solve the problem?
Further to ply's answer, what you have to remember is when you populate an object-based form, you're really taking a Model's attributes & populating them
form_for:
Typically, a form designed to create or update a resource reflects the
identity of the resource in several ways: (i) the url that the form is
sent to (the form element's action attribute) should result in a
request being routed to the appropriate controller action (with the
appropriate :id parameter in the case of an existing resource), (ii)
input fields should be named in such a way that in the controller
their values appear in the appropriate places within the params hash,
and (iii) for an existing record, when the form is initially
displayed, input fields corresponding to attributes of the resource
should show the current values of those attributes.
--
You are populating the Comment model object - this will have attributes defined in your database, such as body, title etc
One of the attributes in the Comment model is the review_id foreign_key
To the Comment model, it does not matter how review_id is passed to it; just that it's done. This is why it does not matter if you use a text_field to input the id directly, or if you use a select tag to help the user select the item they want
--
collection_select
<%= f.collection_select(:review_id, Review.all,
:id, :title,
{:prompt => 'Please select the review of this comment'}) %>
This will give you a select box where you can pick the review
--
Nested Route
A much better way to do this is to use a nested route, so you can set review_id from the parmas:
#config/routes.rb
resources :reviews do
resources :comments #-> /reviews/1/comments/new
end
#app/controllers/comments_controller.rb
def create
#comment = Comment.new(comment_params)
#comment.save
end
private
def comment_params
params.require(:comment).permit(:content).merge(review_id: params[:review_id])
end
Not sure if I follow, but could you just use a select tag here?
This assumes you have an instance variable named #reviews defined in your controller that will be available.
In this case #reviews could be something like Review.all
select_tag "review", options_from_collection_for_select(#reviews, "id", "title"), prompt: "Select a review"

form_for : how to bring 2 variables into view

How can i bring 2 variables into the view. I am newbie in Ruby on rails.
What will the sytax to bring 2 or more values into a view.
<%= form_for(#user) do |f| %>
EDIT :
<%= form_for(#user) do |f| %>
prohibited this user from being saved: </h2>
<u1>
<% #user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</u1>
</div>
<% end %>
<%= debug #user %>
<div class = "field">
<%= f.label :email %><br/>
<%= f.text_field :email %>
</div>
Let's say that in the above code I want to print values from 2 objects and also submit them. How can I do that ?
Well, if you need to use 2 variables, I think it would be better to use two separate forms because they are unrelated. If two variables have relations to each other, you should use accepts_nested_attributes_for and fields_for to do work.
http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html
http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-fields_for
from your above comment "I am talking about loading 2 model into one form" I think you need to use two model in one form so rails cast produce good episode on using nested model for form .
You can use accepts_nested_attributes_for for eg. for survey is one model and question is another model you can use question as nested_attributes in survey and same you can use answers model in survey model in same form.
For more you can read following link.
http://railscasts.com/episodes/196-nested-model-form-part-1?view=asciicast
I hope this will help you.
Thanks.

Can I have both index and create actions in the index view?

Using the perennial example of a Blog webapp (and all resources are currently automatically mapped in routes.rb):
I have a simple index page that lists all my Post titles. I would like to add a form at the bottom of this page to quickly create new Posts.
I'm new to Rails and can't seem to figure this out! Please help!
Try something like:
<% form_for Post.new do |form| %>
(Insert fields here:)
<%= form.label :fieldname %>
<%= form.text_field :fieldname %>
<%= form.submit "Create" %>
<% end %>
Add this to app/views/posts/index.html.erb.
Yes you have both index and create actions in the index view.
display list in a index.html.erb then form to create a new post.
after creating new post redirect to index action only.

Resources