rails render partial template with collection not working - ruby-on-rails

Found some similar answers, but no one seems to fit.
I also read http://guides.rubyonrails.org/layouts_and_rendering.html, chapter 3.4.5, Rendering collections.
I'd like to render the following partial: (users/_user_append.html.erb)
<%= content_tag_for(:tr, user) do %>
<td class="dim"><%= user.id %></td>
<td><%= user.lastname %></td>
<td><%= user.firstname %></td>
<td><%= user.company %></td>
<td><%= user.email %></td>
<td class="fadeactions col-md-2">
<%= link_to(content_tag(:i, nil, class: 'fa fa-minus-square-o'),
remove_mailgroup_user_path(#mailgroup, user),
:method => :delete, remote: true,
:data => { :confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')),
toggle: "tooltip", title: "Remove user", placement: 'top'
}
)
%>
</td>
<% end %>
The call for rendering looks like:
<%= render partial: 'users/user_append', collection: #users, as: :user %>
...as: :user... should pass the collection to the partial, as far I understand.
However, nothing appears in the browser.
Who finds the bug? Thanks a lot for your help.

After some discussion we realised the problem was not in the way you call your partial, but rather in the way you defined the #users. As they weren't defined correctly, there was no way for the partial to receive the :user param.
The solution was to change
<%= render partial: '/users/user_append', collection: #users, as: :user %>
to
<%= render partial: '/users/user_append', collection: #mailgroup.users, as: :user %>

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

Rails: How to DRY up multiple use of a partial

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

render from another index scaffold

I continue with this problem
Another Post
But somebody told me that if i want i can pass parameteres in the render, but i dont know how to do it, I mean here
<%= render :file => "userscuentas/index" %>
SO maybe I can pass the #userscuentas as parameteres
I really need your help
Thanks
From your http://pastebin.com/PuX5JheJ
change app/views/userscuentas/index.html.erb to
<%= render "list", :userscuentas => #userscuentas %>
then make a NEW file called app/views/userscuentas/_list.html.erb with this code
<% userscuentas.each do |userscuenta| %>
<tr>
<td><%= link_to userscuenta.id, userscuenta_path(userscuenta) %></td>
<td><%= userscuenta.nombre %></td>
<td><%= userscuenta.nro_cuenta %></td>
<td><%= userscuenta.tipo_cuenta %></td>
<td><%= userscuenta.user_id %></td>
<td><%=l userscuenta.created_at %></td>
<td>
<%= link_to t('.edit', :default => t("helpers.links.edit")),
edit_userscuenta_path(userscuenta), :class => 'btn btn-mini' %>
<%= link_to t('.destroy', :default => t("helpers.links.destroy")),
userscuenta_path(userscuenta),
:method => :delete,
:data => { :confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')) },
:class => 'btn btn-mini btn-danger' %>
</td>
</tr>
<% end %>
You will also have to change how you are calling it in app/views/users/layout_users.html.erb
Also make sure (after you have changed this) that the #userscuentas variable is set in the controller action that references this view.
<li>Cuentas</li>
<div class="tab-pane" id="tab4">
<p>
<%= render "userscuentas/list", :userscuentas => #userscuentas %>
</p>
</div>
I'm kind of unsure about the structure of your application, but your new.html.erb will also not work in the way you are calling that partial because you have to set the #usersuentas variable before it will render properly. You are also calling there a view, and not a partial.
app/views/users/new.html.erb
<%= render "userscuentas/list", :userscuentas => #userscuentas %>
This is assuming you have to populate your #userscuentas variable in the controller side as well, so
userscuentas_controller.rb
def new
#userscuentas = #user.userscuentas.all
#userscuenta = Userscuenta.new
end
Assuming the file trying to be rendered is a partial, try this:
<%= render 'userscuentas/index', :userscuentas => #userscuentas %>
You can then access the variable in the partial using usercuentas
EDIT
For the partial, do the following to prevent the nil error:
<% if !userscuentas.nil? %>
#Do whatever you have to do here
<% end %>

Why my form won't submit correctly?

I have User model and Comment model using acts_as_commentable_with_threading
I'm trying to put the comment function on each User's show page with partial.
But When I try to submit a form, it shows routing error.
Why is this?
Error
Routing Error
No route matches [POST] "/user/john/add_comment"
models/user.rb
acts_as_commentable
views/users/show.html.erb
<%= render 'comment', :user => #user %>
views/users/_comment.html.erb
<table>
<tr>
<th>ID</th>
<th>Title</th>
<th>Body</th>
<th>Subject</th>
<th>Posted by</th>
<th>Delete</th>
</tr>
<% #user.comment_threads.each do |comment| %>
<tr>
<td><%= comment.id %></td>
<td><%= comment.title %></td>
<td><%= comment.body %></td>
<td><%= comment.subject %></td>
<td><%= comment.user.user_profile.nickname if comment.user.user_profile %></td>
<td><%= button_to 'destroy', comment, confirm: 'Are you sure?', :disable_with => 'deleting...', method: :delete %></td>
</tr>
<% end %>
</table>
<%= form_for #user, :html => { :class => 'form-horizontal' } do |f| %>
<div class="field">
<%= f.label :body %><br />
<%= f.text_field :body %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
routes.rb
get "user/:id/add_comment" => 'users#add_comment', :as => :add_comment_user
get "user/:id/delete_comment" => 'users#delete_comment', :as => :delete_comment_user
users_controller.rb
def add_comment
#user = User.find_by_username(params[:id])
#user_who_commented = current_user
#comment = Comment.build_from( #user, #user_who_commented.id, params[:users][:body] )
#comment.save
redirect_to :controller => 'users', :action => 'show', :id => params[:users][:id]
flash[:notice] = "comment added!"
end
Because your route is for a GET, and the form is a POST.
It needs to be a post route. Also you are posting to user/:name/add_comment, you should post the the user id. You can use the name but this would need to be unique across all users.
This line is also wrong.
#user = User.find_by_username(params[:id])
You can either pass in the params[:username] of find_by_id

How do I do this without using a double loop?

I'm attempting to use the fields_for command to combine two models edit functions. I'm editing several variables. With these variables I'd like to include some basic information that is associated with the model, such as #line_item.inventory.item. The only way I could accomplish this is by creating a double loop which doesn't work for obvious reasons. Is there a way to pass two arguments into a for loop?
ie. fields_for :line_items & #order.line_items do ???
<% f.fields_for :line_items do |f| %>
<% for line_item in #order.line_items do %>
<td><%= line_item.inventory.item %></td>
<td><%= f.text_field :inventory_id, :size => 3 %></td>
<td><%= line_item.inventory.unit2_id %></td>
<td><%= line_item.inventory.catalognumber %></td>
<td><%= f.text_field :quantity, :size => 3 %></td>
<td> <%= f.text_field :item_price, :size => 3 %></td>
<td><%= f.text_field :total_price, :size => 3 %></td>
<td><%= f.check_box :received %><b>Received</b> </td>
<td><%= f.text_field :notes %></td>
<td><%= link_to 'remove item', line_item, :confirm => 'Are you sure?', :method => :delete %></td>
</tr>
<% end %>
<% end %>
You should look at accepts_nested_attributes_for. When used correctly, it can solve your problem.
Assuming the encompassing form is for an order you want to add the following to the Order model, if it isn't already there.
class Order < ActiveRecord::Base
has_many :line_items
accepts_nested_attributes_for :line_items
end
And the view:
<% form_for :order do |f| %>
...
Order specific fields
...
<% f.fields_for :line_items do |line_item_form| %>
<% line_item = line_item_form.object
<td><%= line_item.inventory.item %></td>
<td><%= line_item_form.text_field :inventory_id, :size => 3 %></td>
<td><%= line_item.inventory.unit2_id %></td>
<td><%= line_item.inventory.catalognumber %></td>
<td><%= line_item_form.text_field :quantity, :size => 3 %></td>
<td> <%= line_item_form.text_field :item_price, :size => 3 %></td>
<td><%= line_item_form.text_field :total_price, :size => 3 %></td>
<td><%= line_item_form.check_box :received %><b>Received</b> </td>
<td><%= line_item_form.text_field :notes %></td>
<td><%= link_to 'remove item', line_item, :confirm => 'Are you sure?', :method => :delete %></td>
</tr>
<% end %>
fields_for, when used with accepts_nested_attributes_for and given an association, will loop through all items already associated with the object of the parent form builder. In all other cases fields_for does not use a loop.
First of all, if you need to do nested models I recommend you to view these three railscasts innmediately.
In your case I would start by interchanging the "for" and the "fields for":
<% for line_item in #order.line_items do %>
<% f.fields_for :line_item do |f| %>
... (snip)
<% end %>
<% end %>
Then I would realize that a I could move the entire fields_for to a partial view and use a render call with a :collection parameter:
in order.html.erb:
<%= render :partial => :line_item, :collection => order.line_items %>
in _line_item.html.erb:
<% f.fields_for :line_item do |f| %>
... etc
Now you don't have any "for". :)
Also, your "line items" are inside an "#order" object, so I imagine there's a form_for somewhere up:
<% form_for #order ... %>
...
<%= render :partial => :line_item, :collection => order.line_items %>
...
<% end %>
Now you have your views fixed. But you still have to make your Orders model "handle" its children correctly.
I'm not sure there is really a way for this, since the fields_for block and the for loop are basically 2 different things. So it's not really a "double loop".

Resources