Rails 3.1 multiple objects on one form - ruby-on-rails

I've checked out a lot of questions for putting multiple objects on one form, but they seem to be out of date.
I have a bunch of user objects:
def index
#users = User.all
#user = current_user
end
that I need to edit in a form. They all have roles which will be edited on the form. The form is rendered in a partial, and nothing shows up, just 'admin form' plaintext.
users/_admin.html.erb
admin form
<% form_for "user[]", :url => users_path do |f| %>
<ul>
<li class="layout">
<div class="header"><h2>Users</h2></div>
<table>
<thead>
...
</thead>
<tbody>
<% #users.each do |user| %>
<% puts "USER #{user}" %>
<tr>
<td><%= f.check_box(:editor) %></td>
<td><%= f.check_box(:admin) %></td>
<td><%= user.first_name %> <%= user.last_name %></td>
<td><%= user.email %></td>
</tr>
<% end %>
</tbody>
</table>
</li>
</ul>
<%= submit_tag "Save"%>
<% end %>
Just the plaintext is rendered, but no form. Any ideas on how to fix it? I've tried the suggestions in these posts: one two three, but they're out of date.
Thank you.

You need to use <%= .. %> in Rails 3.1:
<%= form_for "user[]", :url => users_path do |f| %>

Related

form_for submit button does not work for ruby on rails

my form_for submit button only works partially; the data is saved in the database but the redirection fails. Here are the relevant codes for the form:
app/views/orders/new.html.erb
<h1>Menu</h1>
<%= link_to "Back to channel", current_channel_path %>
<div class="container">
<table class="table table-striped">
<thead>
<tr>
<th>Meal</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<% #menu_items.each do |t| %>
<p>
<tr>
<td><%= t.name %></td>
<td><%= number_to_currency(t.price) %></td>
<%= form_for (#order), url: orders_path, remote: true do |f| %>
<td><%= f.number_field :quantity, value: 1, class: "form-control", min: 1 %></td>
<%= f.hidden_field :meal, :value => t.name %>
<%= f.hidden_field :unit_price, :value => t.price %>
<td><%= f.submit "Order", class: "btn btn-primary" %></td>
<% end %>
</tr>
</p>
<% end %>
</tbody>
</div>
Here are the codes for routes.rb
Rails.application.routes.draw do
#For Orders
get 'orders' => 'orders#new'
post 'orders' => 'orders#create'
get 'all_orders' => 'orders#show'
resources :users
resources :orders
Here are the relevant codes for orders
def new
#menu_items = MenuItem.all
#order = Order.new
end
def create
#order = current_channel.orders.build(order_params)
#order.user = current_user
if #order.save
flash.now[:success] = "Order has been recorded!"
redirect_to all_orders_path
else
flash.now[:danger] = "Order was not recorded!"
render 'new'
end
end
I read that the submit button may not work as it is nested in the table. I have tried putting the form outside of the table but the submit still does not redirect; the submit button however creates the record in the orders database in both cases. Any idea why this is the case? Thanks in advance for any help!
You need a route set for the index path which isn't listed above. If you're following standard crud conventions you should just use "resources :orders" in your routes files which will generate the post/put/delete/get routing you need. Then your redirection will work.

Form with route direction does not work

I have a form set up with the following code:
<h2>Add collaborators to the wiki </h2>
<table>
<tr>
<th>Name</th>
<th>Email</th>
<th>Give Access</th>
</tr>
<tr>
<%= form_for (#collaboration) do |f| %>
<% #users.each do |user| %>
<td><%= user.name %></td>
<td><%= user.email %></td>
<td> <%= f.collection_select :user_id, User.all, :id, :name, prompt: true %> </td>
</tr>
<%= f.submit %>
<% end %>
</table>
<%= f.submit %>
<% end %>
And my routes are set up like this:
resources :wikis do
resources :collaborations
end
And in my controller I defined my variables like this:
def new
#wiki = Wiki.find(params[:wiki_id])
#collaboration = #wiki.collaborations.new
end
But when I visit the page clicking on a link I created
<%= link_to 'Add Collaborator', new_wiki_collaboration_path(#wiki) %>
I still get this error:
undefined method `collaborations_path' for #<#<Class:0x007f8b6a5a8a00>:0x007f8b67820c90>
Any thoughts on what goes wrong here?
Your form here just goes to collaboration_path which you've not defined.
<%= form_for (#collaboration) do |f| %>
<% end %>
You need to include the wiki
<%= form_for ([#wiki, #collaboration]) do |f| %>
<% end %>

Rails show action where `id` is not explicitly stated in params

In my app, I have a view that shows a number of products. If a product has an active "deal" on it, a link to that deal is given for that deal that links to the show action for that deal, as below.
<tr>
<% #item.inventory_items.each do |p| %>
<td><%= link_to image_tag("#{p.vendor.image_url}"), vendor_path(p.vendor) %></td>
<td class="price">$<%= p.price %></td>
<td>
<% if Deal.where(:product_code => p.product_code, :vendor_id => p.vendor_id).exists? %>
<%= link_to "See It!", deal_path(Deal.where(:product_code => p.product_code, :vendor_id => p.vendor_id)) %>
<% else %>
<% end %>
</td>
<td>
......
</td>
</tr>
The problem I'm having is that my show action for Deal is looking in params for a deal id. This deal id isn't really in params, so how can I tell this Deal show action which deal I'm interested in? Thanks in advance! As an aside, my above code feels really verbose and very un-rails-like in my if block. If you have any suggestions for it, any advice is much appreciated.
deal/show.html.erb
<%= link_to image_tag("#{#deal.vendor.image}") %>
<%= #deal.vendor.address %>
<%= image_tag(#deal.image) %>
Deal show action:
def show
#deal = Deal.find(params[:id])
end
Try
<%= link_to "See It!", deal_path(Deal.where(:product_code => p.product_code, :vendor_id => p.vendor_id).first) %>
Your code is definitely not very rails-like.
What you should be able to do is something like this:
<tr>
<% #item.inventory_items.each do |p| %>
<td><%= link_to image_tag("#{p.vendor.image_url}"), vendor_path(p.vendor) %></td>
<td class="price">$<%= p.price %></td>
<td>
<% if p.deal.exists? %>
<%= link_to "See It!", deal_path(:id => p.deal.id)) %>
<% else %>
<% end %>
</td>
<td>
......
</td>
</tr>
Note that you can pass parameters along in a link_to. See this question - link_to send parameters along with the url and grab them on target page
If you're models are setup correctly, you shouldn't have to be doing queries in your views.

Get validation errors on a partial's form

So I have a form in my Rails app that's on a _form.html.erb.
I'm displaying this partial on every page of my site, so it doesn't really have any model logic behind it, and the User created form it is made on the fly in the view:
<%= form_for User.new, :validate => true do |f| %>
<table>
<tr>
<td><%= f.label :invitation_token, "Invite Token" %></td>
<td><%= f.text_field :invitation_token, :placeholder => "From your inbox…".html_safe %></td>
</tr>
<tr>
<td colspan="2"><br><%= f.submit "Sign Up" %></td>
</tr>
</table>
<% end %>
I have some validations in my User model, but how would I display those validation errors in my view after reload?
I've tried User.new.errors.inspect but the messages parameter is always empty, even if there's a validation error.
There are a few ways to do this. Since you will likely want to render these error messages in many places, create a shared folder in your views app/views/shared/_error_messages.html.erb and add this partial:
<% if object.errors.any? %>
<ul>
<% object.errors.full_messages.each do |msg| %>
<li>* <%= msg %></li>
<% end %>
</ul>
<% end %>
Now in your view add the code to render the error messages in you form just below form for
<%= render 'shared/error_messages', object: f.object %>

rails 3 rendering error div_for?

I am working a on rails 3 project and am trying to render a partial on the user profile page. Rendering works fine for everything except photo. When I try to access a user profile page I get the following error
undefined methodmodel_name' for NilClass:Class`
user show.html.erb
def show
#user= User.find(params[:id])
#photo = Photo.find_by_id(params[:id])
end
In the profile show.html.erb
<%= content_tag :h2, "My photos" %>
<% photo = #user.photos %>
<% if photo.blank? %>
<%= link_to 'Create photo', new_photo_path %>
<% else %>
<%= render :partial => 'photos/photo', :locals => {:photo => #photo} %>
<% end %>
Here is the partial that it is rendering
<%= div_for photo do %>
<table>
<tr>
<th>Title</th>
<th>Date</th>
<th>Extra</th>
</tr>
<tr>
<td><%= photo.title %></td>
<td><%= photo.date %></td>
<td><%= photo.extra %></td>
<td><%= link_to 'View photos', photo %></td>
</tr>
</table>
<% end %>
Any ideas or suggestions on how I can get rid of this error? Thanks in advance
The error is thrown because in :locals => {:photo => #photo}, #photo is null
Note that you are sending the list #user.photos, not a single image.
Here #photo = Photo.find_by_id(params[:id]) you are getting the photo by id, photo_id. I believe you want to find the user's photo
#photos = #user.photos
#for only one photo, also you need to make sure its not null
#photo = #user.photos.first
There isn't photo with this id in database #photo = Photo.find_by_id(params[:id])
And, therefore, you sending nil object to partial. If you want to show all user photos, try this.
<%= content_tag :h2, "My photos" %>
<% photos = #user.photos %>
<% if photos.empty? %>
<%= link_to 'Create photo', new_photo_path %>
<% else %>
<% photos.each do |photo| %>
<%= render :partial => 'photos/photo', :locals => {:photo => photo} %>
<% end %>
<% end %>
When using the div_for note is nil so I would try accessing it by iterating through the code Like I've done below. Then photos should be accessible now.
<% #photos.each do |photo| %>
<%= div_for photo do %>
Code here
<% end %>
<% end %>

Resources