How to loop all the elements in the DB using RoR? - ruby-on-rails

I use this to loop the products...
<% form_for :product, #products, :url => { :action => "add_to_cart" } do |f| %>
<%= product.title %>
<%= product.price %>
<%= submit_tag 'Make Order' %>
<% end %>
In my DB, I have
product:
title:abc price:874
title:cde price:98
title:efg price:18
but I can only get the efg 18.0 in my result, I miss other records on my result,
any ideas on that?

I suppose that you need an extra form for each product, (based on the add_to_cart action).
form_for helper generates a form for one object, so you will need to iterate through your objects and create a form for each one.
Something like that is probably what you need:
<% for product in #products %>
<% form_for product, :url => { :action => "add_to_cart" } do |f| %>
<%= product.title %>
<%= product.price %>
<%= f.submit 'Make Order' %>
<% end %>
<% end %>

form_for creates a form for a single object. If you want to create a form for multiple objects, I suggest you take a look at this question: Multiple objects in a Rails form

Related

Multiple fields not display in single form and model Rails

I have model product. I want to create multiple record in single model (product), but fields not display in view
#controller
#products = Array.new(3){ Product.new }
# view
<%= form_tag create_product_path, :method => :post, :class => "form-horizontal", 'role' => "form" do %>
<% #products.each_with_index do |product, index| %>
<% fields_for "products[#{index}]", product do |f| %>
<%= f.text_field :date %>
<%= f.text_field :name %>
<% end %>
<% end %>
<%= submit_tag "Submit", :class => "btn btn-primer" %>
Look at this screenshoot, fields not appear. Can anyone tell me, why new form method using array not appear?
Don't forget about <%= on fields_for
read about fields_for
rails 2.x - 3.0
<% fields_for "products[#{index}]", product do |f| %>
rails > 3.1.x
<%= fields_for "products[#{index}]", product do |f| %>

Limit User to 1 Like/Dislike per Post

I have a listing model (which allows comments) and users can like (thumbs up) or dislike (thumbs down) the listing. It works at the moment but I want to iterate over the likes for a specific listing, and if any like's user_id listing.likes.user_id matches the current users ID current_user.id then remove the form to like (users can add a reason why they are liking the listing)
<%= form_for([#listing, #listing.likes.build]) do |f| %>
<%= f.hidden_field :user_id, :value => current_user.id %>
<%= f.text_field :body %>
<%= f.submit %>
<% end %>
I have something halfway there that checks if the current likes user_id matches the current user id, if so provide a link to delete (remove/unlike) the like.
<% if current_user.id == like.user_id %>
<%= link_to '[ Delete Like ]', [like.listing, like],
method: :delete,
data: { confirm: 'Are you sure?' } %>
<% end %>
How would I go about using the code to remove the like form if the user has already created a like/if the user's ID matches the user_id of a like created for a specific listing(something like this?)
<% if current_user.id == listing.likes.any.user_id %>
<% else %>
<%= form_for([#listing, #listing.likes.build]) do |f| %>
<%= f.hidden_field :user_id, :value => current_user.id %>
<%= f.text_field :body %>
<%= f.submit %>
<% end %>
<% end %>
I think you had the right idea with the any method, but were not using it correctly. any can accept a block in which you can do your user_id comparison, like so:
<% if listing.likes.any{|like| like.user_id == current_user.id } %>
In this case, any will return true the instant the condition in the block evaluates to true.
Let me know whether this works.
Side Note
If my method works for you, you may like to further clean up your view code by moving that check in to the Listing model as a helper method. Something like this:
class Listing < ActiveRecord::Base
# ... other stuff
def has_comment_from?(target_user)
likes.any{|like| like.user_id == target_user.id }
end
end
And then you can simply call it from the view like so:
<% if listing.has_comment_from? current_user %>
Found a partial solution but it stops the user from commenting after 1 comment, not 1 comment per listing.
<% #listing.likes.each do |like| %>
<% if current_user.id == like.user_id %>
<% else %>
<%= form_for([#listing, #listing.likes.build]) do |f| %>
<%= f.hidden_field :user_id, :value => current_user.id %>
<%= f.text_field :body %>
<%= f.submit %>
<% end %>
<% end %>
<% end %>

Rails how can I pass multiple values through check_box_tag?

I am trying to pass multiple values to a custom function that I created through the check_box_tag, however I don't really know how to do it, I have check online for hours but didn't help.
Basically I have a details view, and I try to pass the date and id information of the detail to the controller and call the create method.
<%= form_tag( { :action => 'create' } ) do %>
<% #details.each do |detail| %>
<%= check_box_tag 'date[]', detail.date, false, :id => detail.id %>
<%= detail.date %>
<% end %>
<%= submit_tag 'Register!' %>
<% end %>
I try to set the custom value but when I type params in the debugger this is what it shows
{"utf8"=>"✓", "authenticity_token"=>"3PKBBKNmXyAfdSllTWBFP8EafhbrJ8rCgOeOp2NbeBA=", "date"=>["2013-06-08"], "commit"=>"Register!", "action"=>"create", "controller"=>"line_items"}
I really don't know how should I do it.
Thank you for your answer in advance!
please using array dates.
<%= form_tag( { :action => 'create' } ) do %>
<% #details.each do |detail| %>
<%= check_box_tag 'detail[dates][]', detail.date, false, :id => detail.id %>
<%= detail.date %>
<% end %>
<%= submit_tag 'Register!' %>
<% end %>

Rails checkboxes and serialized data

I'm trying to figure out whats the best way to get checkboxes to properly show their current state. This is what I have in my form
<%= form_for #user, :url => user_notification_preferences_path(#user), :method => :put do |f| %>
<%= f.fields_for :notification_preferences, #user.notification_preferences do |p| %>
<%= p.check_box :notify_on_friend_post %>
<%= p.check_box :notify_on_friend_post %>
<%= p.check_box :notify_on_friend_request %>
<%= p.check_box :notify_on_friend_comment %>
<% end %>
<%= f.submit %>
<% end %>
notification_preferences is a serialized hash on my user model
class User < ActiveRecord::Base
serialize :notification_preferences, Hash
My issue that is no matter what I try, I can not get the check boxes to reflect the existing state of the hash values. IE, if the hash already contains :notify_on_friend_post => 1, then the check box for that value should be checked.
The form posts the data fine, and I'm able to update my model as well.
Update
using check_box_tag I can get this to work
<%= p.hidden_field :notify_on_friend_post, :value => "0" %>
<%= check_box_tag "user[notification_preferences][notify_on_friend_post]", "1", #user.notification_preferences[:notify_on_friend_post] == "1" ? true : false %>
ugly but working, still hoping I'm missing something very obvious
I ran into this problem and solved it in a simpler way.
<%= form_for #user do |f| %>
<%= f.fields_for :notifications, #user.notifications do |n| %>
<%= n.check_box :new_task, checked: #user.notifications[:new_task] == "1" %>
<% end %>
<%= f.submit %>
<% end %>
In this way you let the magic of check_box to the work and don't need to have a hidden_field because Rails will provide one for you. Still unsure why you need a "checked" field, but it seemed to not work without one.
Try something like this:
<%= form_for #user, :url => user_notification_preferences_path(#user), :method => :put do |f| %>
<%= check_box_tag "user[notification_preferences][]", :notify_on_friend_post, #user.notification_preferences.try(notify_on_friend_post) %>
<%= f.submit %>
<% end %>

Nested Rails forms and using label_tag, checkbox_tag and other form_tag functions

In regular forms in Ruby on Rails, if using form_for to build a model, as the API docs state, form_for doesn't create an exclusive scope, and it's possible to use form_tag functions within the form_for form.
For example:
<% form_for :person, #person, :url => { :action => "update" } do |f| %>
First name: <%= f.text_field :first_name %>
Admin? : <%= check_box_tag "person[admin]", #person.company.admin? %>
<% end %>
However, in a nested form, the labels and fields have names that are automatically generated by Rails to be associated with a given nested model and not to overlap if multiple nested models are created at once. Is it possible to still use the form_tag functions?
I'd like to do something like this:
<% person_form.fields_for :children do |child_form| %>
Name: <%= child_form.text_field :name %>
Give up for Adoption?: <%= check_box_tag "adoption_" + child_form_index, false %>
<% end %>
However, I don't know how to get access to the child_form's index to ensure that check_box_tag has a unique value if there are multiple children.
Is what I'm trying to do possible?
See the docs for fields_for under one-to-many.
It looks to me like basically you can just use each (or each_with_index) and pass the block variable along with the symbol:
<% form_for #person, :url => { :action => "update" } do |person_form| %>
...
<% #person.children.each_with_index do |child, index| %>
<% person_form.fields_for :children, child do |children_fields| %>
Name: <%= children_fields.text_field :name %>
Give up for Adoption?: <%= check_box_tag "adoption_" + index, false %>
<% end %>
<% end %>
<% end %>
Of course, you'll have to handle the "offer for adoption" login on your own.

Resources