checkboxs in a table created via form_for - ruby-on-rails

I'm new to RoR so apologies if the answer is super simple. I'm trying to create a table that allows users to select other users that can collaborate on a wiki. The issue I'm having is that no matter which checkbox you select on the table. It only toggles the topmost option.
here is the code in question:
<%= form_for [#wiki, #wiki.collaborators.build] do |f| %>
<table class="bordered hoverable">
<tbody>
<% #users.each do |user| %>
<tr>
<td><%= user.name %></td>
<td class="right-align"><%= f.check_box :user_id %><%= f.label :user_id, "Give Access" %></td>
</tr>
<% end %>
</tbody>
</table><br /><br />
the controller values in new
def new
#wiki = Wiki.find(params[:wiki_id])
#collaborator = Collaborator.new
#users = (User.all - [current_user])
end

The problem here is that through check_box's you can't get more than one user selected. In order to select multiple data, you need to use f.collection_select.
Here's how:
<%= f.collection_select :user_id, #users, :id, :name, {prompt: "Please select collaborators"}, {multiple: true} %>

To select multiple the the name of the checkbox should not be :user but contain the user id. Try something like that:
<%= form_for [#wiki, #wiki.collaborators.build] do |f| %>
<%= f.fields_for :collaborators do |c| %>
<table class="bordered hoverable">
<tbody>
<% #users.each do |user| %>
<tr>
<td><%= user.name %></td>
<td class="right-align"><%= c.check_box user.id %><%= f.label user.id, "Give Access" %></td>
</tr>
<% end %>
</tbody>
</table><br /><br />
<% end %>
<% end %>
The controller would then recieve params like that:
{:collaborators => {1 => '0', 2 => '1'}
showing that user with id 1 was not checked, user with id 2 was checked

Related

Having an issue with strong params during mass assignment

I'm trying to update multiple records with one form:
Here's the code in the view:
<%= form_for :product, :url => admin_products_update_multiple_path, :html => { :method => :put } do %>
<table>
<tr>
<th>Supplier Name </th>
<th>Product Name </th>
<th>type_name</th>
<th>brand</th>
<th>image</th>
</tr>
<% #products.each do |product| %>
<%= fields_for "product[]", product do |product_fields| %>
<tr>
<td><%= product.supplier_name %> </td>
<td><%= product.subcategory_name %> </td>
<td><%= product_fields.text_field :type_name %></td>
<td><%= product_fields.text_field :brand %></td>
<td><%= product_fields.text_field :image %></td>
</tr>
<% end %>
<% end %>
</table>
<div class="actions">
<%= submit_tag %>
</div>
<% end %>
... and here's the controller action I'm calling to update:
def update_multiple
params['product'].keys.each do |id|
#product = Product.find(id.to_i)
#product.update_attributes(product_params)
end
flash[:notice] = "Update products successfully"
redirect_to(admin_products_path)
end
private
def product_params
params.require(:product).permit(:id, :type_name, :brand, :image)
end
When I run the method, I'm getting a 'Unpermitted parameters' error showing all the ids it's trying to update. Any ideas? Thanks in advance!

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 %>

Advanced search form shows more tables for more results

I'm following Advanced search form episode from Railscasts.
This is the search model:
search.rb
class Search < ActiveRecord::Base
attr_accessible :keywords
def segnalazione_animalis
#segnalazione_animalis ||= find_segnalazione_animalis
end
private
def find_segnalazione_animalis
segnalazione_animalis = SegnalazioneAnimali.order(:Titolo)
segnalazione_animalis = segnalazione_animalis.where("Titolo like ?", "%#
{keywords}%") if keywords.present?
segnalazione_animalis = segnalazione_animalis.where("Titolo like ?", "%#
{keywords}%") if keywords.present?
segnalazione_animalis = segnalazione_animalis.where("classe like ?", "%#
{keywords1}%") if keywords1.present?
segnalazione_animalis = segnalazione_animalis.where("specie like ?", "%#
{keywords2}%") if keywords2.present?
segnalazione_animalis
end
end
I have a searches_controller.rb
class SearchesController < ApplicationController
def new
#search = Search.new
end
def create
#search = Search.create!(params[:search])
redirect_to #search
end
def show
#search = Search.find(params[:id])
end
end
The new.html.erb file is
<%= form_for #search do |f| %>
<div class="field">
<%= f.label :keywords %><br />
<%= f.text_field :keywords %>
</div>
<div class="field">
<%= f.label :keywords1,"Classe" %><br />
<%= f.text_field :keywords1 %>
</div>
<div class="field">
<%= f.label :keywords2,"Specie" %><br />
<%= f.text_field :keywords2 %>
</div>
<div class="actions"><%= f.submit "Search" %></div>
<% end %>
And the show file:
<h1>Search Results</h1>
<%= render #search.segnalazione_animalis %>
I take the partial rendered from the index file of my segnalazione_animalis folder:
_segnalazione_animali.html.erb
<table class="table1">
<tr>
<th>Titolo:</th><br>
<th>Classe:</th>
<th>Creato il:</th>
<th>Ultima Modifica il:</th>
<th></th>
</tr>
<% #search.segnalazione_animalis.each do |segnalazione_animali| %>
<tr>
<td><%= segnalazione_animali.Titolo %> </td>
<td><%= segnalazione_animali.classe %>
<td><%= l(segnalazione_animali.created_at, format:"%e %B %Y %k:%M:%S")</td>
<td><%= l(segnalazione_animali.updated_at, format:"%e %B %Y %k:%M:%S")%>
</td>
<td><%= link_to 'Mostra', [segnalazione_animali.user, segnalazione_animali]
%></td>
</tr>
<% end %>
</table>
When the search works and there is more than one result it shows more tables with every result.
Example: it find two results, it shows two tables with the two results.
Well, yes, you display the results using a partial and the partial defines a new table so if there are multiple animals there will be multiple tables. When you render a collection rails will automatically render the corresponding partial for EACH object.
If you want only one table, then do this in the show file
<h1>Search Results</h1>
<table class="table1">
<tr>
<th>Titolo:</th><br>
<th>Classe:</th>
<th>Creato il:</th>
<th>Ultima Modifica il:</th>
<th></th>
</tr>
<%= render #search.segnalazione_animalis %>
</table>
And in the partial just include the
<tr>
<td><%= segnalazione_animali.Titolo %> </td>
<td><%= segnalazione_animali.classe %>
<td><%= l(segnalazione_animali.created_at, format:"%e %B %Y %k:%M:%S")</td>
<td><%= l(segnalazione_animali.updated_at, format:"%e %B %Y %k:%M:%S")%></td>
td><%= link_to 'Mostra', [segnalazione_animali.user, segnalazione_animali] %></td>
</tr>
All part of the magic of rails. :)

Rails 3 submit a form with multiple records

I'm new to rails so this is probably a basic question. I am trying to create a form where the user can create 3 records at once. I want the user to only have to click the submit button once. I'm submitting to my Review model a name, comment, and rating. Currently, only the last record is entered into the database.
<%= form_for([#user,#review]) do |f| %>
<table>
<tr>
<td>Rank</td>
<td>Name</td>
<td>Comment</td>
</tr>
<tr>
<td>1</td>
<td><%= f.text_field :name %></td>
<td><%= f.text_field :comment %></td>
<%= f.hidden_field :rating, :value=> "5" %>
</tr>
<tr>
<td>2</td>
<td><%= f.text_field :name %></td>
<td><%= f.text_field :comment %></td>
<%= f.hidden_field :rating, :value=> "3" %>
</tr>
<tr>
<td>3</td>
<td><%= f.text_field :name %></td>
<td><%= f.text_field :comment %></td>
<%= f.hidden_field :rating, :value=> "1" %>
</tr>
</table>
<div class="actions">
<%= f.submit "Create my top 3" %>
</div>
<% end %>
Any advice is appreciated. Thanks.
I would recommend using fields_for for this:
<%= form_for([#user, :reviews]) do |f| %>
<% #reviews.each do |review| %>
<%= fields_for review do |r| %>
<%= render "reviews/form", :r => r %>
<% end %>
<% end %>
<% end %>
To make this work, you will need to build as many review objects as you require in your controller:
def new
# you could also have this in a before_filter...
#user = User.find(params[:id])
#reviews = Array.new(3) { #user.reviews.build }
end
This would create new instances of review records for this user, which is different from new records. Instances are simply Ruby objects. Now because you've called #user.reviews.build three times, you'll see three reviews in your view.
def create
#user = User.find(params[:id])
#reviews = Review.create(params[:reviews])
# Some more logic for validating the parameters passed in
end
This will create three new Review objects and link them to #user, assuming all three are valid.
You'll need to tell rails its an array. First, read this section of this article:
For your purpose, you'll need to build the form by hand:
<%= form_tag 'foo' do %>
<% [1,3,5].each do |i| %>
<%= text_field_tag 'review[][name]' %>
<%= text_field_tag 'review[][comment]' %>
<%= hidden_field_tag 'review[][rating]', :value => i %>
<% end %>
<% end %>

Resources