Rails: How to DRY up multiple use of a partial - ruby-on-rails

Like to DRY up the following code. Created a partial _user.html.erb, which is called either by the users view via
<%= render #users %>
and by the groups view via
<%= render partial: 'users/user', collection: #mailgroup.users, as: :user %>
The partial _user.html.erb is:
<%= content_tag_for(:tr, user) do %>
<td><%= user.id %></td>
<td><%= check_box_tag "user_ids[]", user.id, true %></td>
<td><%= user.firstname %></td>
<td><%= user.lastname %></td>
<td><%= user.function %></td>
<td><%= user.company %></td>
<td><%= user.appendix %></td>
<td><%= user.city %></td>
<td>
<%= link_to button1 ... %>
<%= link_to button2 ... %>
<%= link_to button3 ... %>
<%= link_to button4 ... %>
</td>
<% end %>
Now I like this partial having rendered once with all columns (call 1.), and also with a subset of columns (call 2.). Especially like to hide the check_box_tag in the second column.
I searched around and was confused at the end how to solve: With different layouts? How would I have to do it with partials? Or with checking first from what controller the call comes from? (This doesn't sound very satisfying to me).
In general: How to call the same partial with different subset of columns without maintaining different copies of that partial?

I'm not sure you can use layouts for partials and I agree that checking for controller source is a code smell. I would consider using another local to check if the fields are to be displayed which could be set in the "calling" view e.g.
<%= render #users, locals: {show_buttons: false} %>
<%= render partial: 'users/user', collection: #mailgroup.users, as: :user, show_buttons: true %>
and used in the user partial
<% if show_buttons %>
<td><%= check_box_tag "user_ids[]", user.id, true %></td>
<% end %>
You could dry this out further with a helper method
<td><%= user.id %></td>
<%= check_box(user, show_buttons)
module UsersHelper
def check_box(user, show_buttons)
if show_buttons
content_tag(:td) do
content_tag(:option, "user_ids[]", value: user.id )
end
end
end
end

Related

Rails - Simple_fields_for not submitting multiple records

I'm trying to create a form that allows a user to select different choices for each category on the same form, and each of these will create its own model. My problem is getting the form to submit multiple parameters. My code is as follows:
<%= simple_form_for choices_path do |f| %>
<td><%= person.fullname %></td>
<td><%= person.email %></td>
<td><%= person.phone %></td>
<% if Category.any? %>
<%= f.simple_fields_for :choices do |g| %>
<% Category.all.each do |category| %>
<td>
<%= g.input :item_id, as: :select, collection: booking.venue.menu_items(category) %>
<%= g.hidden_field :admin_id, value: person.id %>
</td>
<% end %>
<% end %>
<% end %>
<td><%= person.completed? %></td>
<td><%= f.submit %></td>
<% end %>
The idea obviously being to create a new form for each category. This works until submitting the data, where only the last form's data is submitted. My paramaters are as follows:
{"utf8"=>"✓", "authenticity_token"=>"tf3DSLGHyOVEVJkcLjSVE9HDJbjn1CIaYBJIfHFw6RYH8tcn0tNilWVIjzyvcjXYm2ovKNO5A31+TktGA8X2+Q==",
"/choices"=>{"choices"=>{"item_id"=>"Dessert 1", "admin_id"=>"3"}},
"commit"=>"Save /choices",
"venue_id"=>"1",
"booking_id"=>"26"}
I can see that its creating a hash and is ready to submit multiple choices, however it is only the last record's data that is submitted.
Any help on how to get multiple records to update is greatly appreciated.
Thanks in advance.
The simple form association helper might be what you are looking for:
link

update database with checkboxes - rails

So I have a users model which is associated to activities and activities are associated to a completed model?.
What I am trying to do is update if an activity is completed when a checkbox is clicked.
Here is my view:
<% #user.completeds.each do |task| %>
<tr>
<td><%= task.activity.name %></td>
<td><%= task.activity.type.name %></td>
<td><%= task.activity.points %></td>
<td><%= check_box_tag 'finished', '1', task.finished %></td>
</tr>
<% end %>
This all works great and shows if an activity is "finished" but I am having a hard time figuring out how to update the database with the checkbox. While I would like it to update when you click the checkbox I am ok with having a save button to save them all at once. Which ever would be easier probably would be best for me as I am just learning rails.
Thank you for any help.
Edit:
To clarify my question, my code above works for showing the data correctly, what I can't figure out is how to turn it into a form so that I can save any changes to the check box values.
The easiest solution would be to use a form and a save button. If you look at the Form Helpers Rails Guide, you can see an example:
<%= check_box_tag(:pet_dog) %>
<%= label_tag(:pet_dog, "I own a dog") %>
You probably want to use form_for, not form_tag though to update your object. See the documentation here.
<%= form_for task do |f| %>
<%= f.label :finished %>:
<%= f.check_box :finished %><br />
<%= f.submit %>
<% end %>
EDIT:
To update multiples, try something like this:
<% form_tag edit_multiple_products_path do %>
<table>
<tbody>
<% #user.completeds.each do |task| %>
<tr>
<td><%= task.activity.name %></td>
<td><%= task.activity.type.name %></td>
<td><%= task.activity.points %></td>
<td><%= check_box_tag 'finished', '1', task.finished %></td>
</tr>
<% end %>
</tbody>
</table>
<%= submit_tag "Update Tasks" %>
<% end %>
Except don't forget to do everything else that the RailsCast mentions.

How do I access data from a joined table in my index.html.erb?

I have a Rails 4 app with two models Campus and Stat. Campus has_many stats and Stat belongs_to Campus.
The problem I have is I can the data from my Campus table in my show action, but not in my index action. Here's the relevant code from the controllers.
def index
#stats = Stat.all
end
def show
end
Here's my show.html.erb:
<p id="notice"><%= notice %></p>
<p>
<strong>Attendance:</strong>
<%= #stat.attendance %>
</p>
<p>
<strong>Salvations:</strong>
<%= #stat.salvations %>
</p>
<p>
<strong>Visitors:</strong>
<%= #stat.visitors %>
</p>
<p>
<strong>Offering:</strong>
<%= #stat.offering %>
</p>
<p>
<strong>Campus:</strong>
<%= #stat.campus.name %>
</p>
<p>
<strong>Date:</strong>
<%= #stat.date %>
</p>
<%= link_to 'Edit', edit_stat_path(#stat) %> |
<%= link_to 'Back', stats_path %>
It's outputs the following:
Attendance: 23
Salvations: 0
Visitors: 3
Offering: 5000.0
Campus: Revelstoke
Date: 2013-07-05
Edit | Back
Here's the relevant portion of my index.html.erb:
<% #stats.each do |stat| %>
<tr>
<td><%= stat.attendance %></td>
<td><%= stat.salvations %></td>
<td><%= stat.visitors %></td>
<td><%= stat.offering %></td>
<td><%= stat.date %></td>
<td><%= stat.time %></td>
<td><%= stat.campus.name %></td>
<td><%= link_to 'Show', stat %></td>
<td><%= link_to 'Edit', edit_stat_path(stat) %></td>
<td><%= link_to 'Destroy', stat, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
The output gives me a undefined method `name' for nil:NilClass for the stat.campus.name
I can't figure out why the difference. What am I doing wrong?
It looks like you have a stat with no campus associated to it in your database.
To check witch one is it, you could go to the rails console and check the campus_id property, printing Stat.all,
That can happen if you are adding your stats programmatically, or maybe you added a form without every model property.
If you don't want that to happen you can use validates in your model. Check this link.
First, you are not initialising #stat in show action, you could do this with:
#stat = Stat.find(params[:id])
Second, you have to be sure #stat has campus associated with it. But as you are not having problems with index, it seems your stat has campus associated, it means that status has a column campus_id which value is a valid id of table campuses.
Update
After reading your comment your stat has not a campus associated, you can show an empty string in these cases with:
<td><%= stat.campus.try(:name) %></td>

Rails Rendering Issue

Whenever I'm trying to render the games partial, the view it's being rendered in gives a nil return.
here is the games partial:
<%= flash[:notice] %>
<tr>
<% #games.each do |game| %>
<td><%= game.name %></td>
<td><%= link_to('Pick!', vote_up_game_path(game.id), :method => :post) %></td>
</tr>
<% end %>
You should pass #games as a local variable to the partial. Consider looking at the documentation on its usage. I also feel the flash-notice should not belong inside the partial. You might also want to correct your code
<% games.each do |game| %>
<tr>
<td><%= game.name %></td>
<td><%= link_to 'Pick!', vote_up_game_path(game.id), :method => :post %></td>
</tr>
<% end %>
You would render the partial as follows
<%= render :partial => "game_partial", :locals => { :games => #games } %>
It is also important to ensure #games isn't nil. If it is, you will still get your error - you should check your controller; typically I'd imagine your controller would have #games = Game.all, of course this is dependent on your particular implementation.

fields_for with association question

How do I use association data from within a fields_for?
I've got a has many through relationship between users, schools and schools_users. A user can have multiple schools and a school has multiple users. In schools_users there is a user_role field in addition to the common user_id and school_id.
In the show view I have:
<% #school.schools_users.each do |user| %>
<tr><td><%= user.user.first_name %> <%= user.user.last_name %></td><td><%= user.user_role %></td></tr>
<% end %>
but I can't figure out how to do the same thing from within the fields_for on the edit page.
<%= f.fields_for :schools_users do |f| %>
<tr>
<td><%= NEED USER NAME HERE %></td>
<td><%= f.select(:user_role, active_role_options)%></td>
<td><%= link_to_remove_fields 'Delete', f %></td>
</tr>
<% end %>
Thanks for any help!
Firstly: You're assigning the block variable of your fields_for to f, which is the same f your form_for uses. You should use a different name, like user_fields.
With that:
<%= f.fields_for :schools_users do |user_fields| %>
<tr>
<td><%= user_fields.text_field :first_name %></td>
...
<% end %>

Resources