Ruby on Rails - Trouble looping through partial using collection - ruby-on-rails

I am having issues using the :collection command for a partial within a form I am creating in rails. I would ideally like to use the :collection command, so I can easily manipulate this section in my .rjs templates (the form will submit and reload the form when the check box is changed, it's a to-do list).
This code works:
<% form_for "list[]", :url => {:action => "checkbox_update"} do |f| %>
<ul id="lists_not_completed">
<% for #list in #lists %>
<%= render :partial => #list, :locals => {:f =>f, :complete => FALSE } %>
<% end %>
</ul>
<% end %>
with the partial:
<% if #list.completed == complete %>
<li><%= f.check_box :completed %>
<%=h #list.name %>
<%= link_to 'Show', list %>
<%= link_to 'Edit', edit_list_path(list) %>
<%= link_to 'Destroy', list, :confirm => 'Are you sure?', :method => :delete %></li>
<% end %>
This code does not work, but I would like it to use this form:
<% form_for "list[]", :url => {:action => "checkbox_update"} do |f| %>
<ul id="lists_not_completed">
<%= render :partial => 'list', :collection => #lists, :locals => {:f =>f, :complete => FALSE } %>
</ul>
<% end %>
with the non-working partial:
<% if list.completed == complete %>
<li><%= f.check_box :completed %>
<%=h list.name %>
<%= link_to 'Show', list %>
<%= link_to 'Edit', edit_list_path(list) %>
<%= link_to 'Destroy', list, :confirm => 'Are you sure?', :method => :delete %></li>
<% end %>
I get the error:
object[] naming but object param and #object var don't exist or don't respond to to_param: nil. It is referring to this line: <li><%= f.check_box :completed %>. I'm not sure if why this doesn't work and have tried many, many different variations, but I can't get it working. Is the form preventing me from doing this? The form_for code is straight from the Rails Way book for listing multiple objects from one model in a form.
Any help on this would be greatly appreciated.

I think that the problem is you've not got #list defined anywhere when you're using the render :partial with a :collection.
The system is looking for #list to match the list[] when you call f.check_box
you could set #list = list in your partial to get around that. I suppose.

Tim's answer is correct, but I'd probably avoid extracting the partial within the form_for loop altogether. I suppose it's a matter of style, but I think the confusion here isn't really worth the cleanup that the partial represents in this case. I'd probably write a partial that included the whole form.

Related

Rails form submit operate like a link_to

So ultimately what I'm trying to do is get the form to be split across two different columns with the status to be in one column and the save button in another column next to the link_to OR have the form's submit operate like a link_to. The form automatically applies some CSS that's causing the issue of splitting the form.
<tbody>
<% #training_resource.spud_users.each do |training| %>
<tr>
<td><%= training.full_name %></td>
<% utr = training.user_training_resources.where(training_resource: #training_resource).first %>
<td class="utr-form">
<%= tb_form_for [:admin, utr], url: admin_update_utr_path(utr), :remote => true, :html => {:id=>'form_id'}, :data => {:errors => :inline, :success => admin_training_resources_path} do |f| %>
<%= f.select :status, UserTrainingResource.statuses.map {|k,v| [k.humanize, k]}, selected: utr.status %>
</td>
<td class="table-actions">
<%= f.tb_save_buttons('', admin_update_utr_path(utr)) %>
<% end %>
<%= link_to 'submit', admin_update_utr_path(utr), :onclick => "$('#form_id').submit()" %>
<%= link_to 'Delete', admin_destroy_utr_path(utr), :method => :delete, :data => {:confirm => 'Are you sure you want to delete this?'}, :class => 'btn btn-danger btn-sm' %>
</td>
</tr>
<% end %>
</tbody>
So what I'm trying to figure out is if there is a way to change the form save button to be a link_to. Right now I have it here under link_to 'submit'. It however does not operate like the tb_save_button as it doesn't redirect to the correct location or save.
You could handle this in the controller.
(example)
def create
if utr.save
redirect_to admin_update_utr_path(utr)
else
# render new form or display the previous view
end
end

How to implement a destroy confirmation form with simple_form?

I'm using Ruby on Rails 4 with simple_form. On my delete page, I would like to display a form confirming the user's decision to destroy the resource in question. Here is the code I am using:
<h2>Delete Page</h2>
<p>Are you sure you want to delete <%= #journalEntry.title %></p>
<%= simple_form_for(#journalEntry, :action => 'destroy') do |f| %>
<%= f.button :submit %>
<% end %>
However, this is getting processed by the update action instead (my server console shows that it is being sent as a PATCH request).
I also tried amending that code to the following, but with the same result:
<%= simple_form_for(#journalEntry, :url => {:action => 'destroy', :id => #journalEntry.id}) do |f| %>
<%= f.button :submit %>
<% end %>
Add :method => :delete option with simple_form_for :
<%= simple_form_for(#journalEntry, :method => :delete) %>
<%= f.button :submit %>
<% end %>

Undefined local variable or method friendship

I'm trying to add some social functionality to my app, and following RailsCast #163 about self-referential association, but I have a problem with deleting friendship.
On user#show page I have 2 columns: with #users and #friends. The show method from UsersController is:
def show
#user = User.find(params[:id])
#users = User.all
#friends = #user.friends
end
Also I'm using <%= render #users %> and <%= render #friends %> partials, both of them renders _user.html.erb from users folder, which is the following:
<tr>
<td>
<%= gravatar_for user, size: 30 %>
</td>
<td>
<%= user.name %>
</td>
<td>
<% if current_user.friends.exists?(user) %>
<%= link_to 'Remove friend', friendship, :method => :delete %>
<% else %>
<%= link_to 'Add friend', friendships_path(:friend_id => user), method: :post %>
<% end %>
</td>
</tr>
Everything is ok with models and controllers, as I've checked everything a hundred times. But when I try to open a page I receive an error undefined local variable or method friendship from this line <%= link_to 'Remove friend', friendship, :method => :delete %>.
Like the error says, friendship is not defined. You need to pass instead of friendship, the user you want to delete. For example:
<%= link_to 'Remove friend', user, :method => :delete %>
or
<%= link_to 'Remove friend', friendship_path(user), :method => :delete %>
Hope this helps!
It looks awful, but seems that current_user.friendships.find_all_by_friend_id(user.id).first instead of friendship solved my problem. But I'm sure that there is more simple solution.
if you have an instance variable defined in your controller (#friendship or #user) use that opposed to user or friendship for the route.
<%= link_to 'Remove friend', #user, :method => :delete %>

Check for nil?, Blank?

I have a model and for some reason I am trying to tell rails if there is nothing created then render add a new show link.
<% if #show != blank? %>
<%= link_to 'Add a new show', new_show_path %></br>
<% else %>
<%= render(:partial => 'shows/show', :locals => {:show => #profile.shows.last}) %>
<% end %>
It adds the Add a new show link but once a show is created I still only see the link and not the partial. If I create the show and put the render at top like so then I can see it but if i delete the show it returns an error.
I've tried these also
<% if #show.present? %>
<%= render(:partial => 'shows/show', :locals => {:show => #profile.shows.last}) %>
<% else %>
<%= link_to 'Add a new show', new_show_path %></br>
<% end %>
<% if #show.blank? %>
<%= link_to 'Add a new show', new_show_path %></br>
<% else %>
<%= render(:partial => 'shows/show', :locals => {:show => #profile.shows.last}) %>
<% end %>
<% if #{model} nil? %>
<%= link_to 'Add a new show', new_show_path %></br>
<% else %>
<%= render(:partial => 'shows/show', :locals => {:show => #profile.shows.last}) %>
<% end %>
and it seems to never give me what I am looking for on both ends. It ethiers shows me the link and nevers shows the partial once created or it shows the partial but when I delete it it gives me an error.
How can I tell rails that if there is no shows created to render the add new link and once there is a show created to render the partial?
Are you actually filtering this by profile? It looks like you're rendering a page for the last show of a profile. (#profile.shows.last)
<% show = #profile.shows.last %>
<% if show.blank? %>
<%= link_to 'Add a new show', new_show_path %>
<br />
<% else %>
<%= render 'shows/show', :show => show %>
<% end %>
Use the .blank? method for the global variable you're trying to tell if it's empty. If its an array or hash. Use .nil? If its supposed to be anything else.

How to loop all the elements in the DB using RoR?

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

Resources