Railscast 198, but using formtastic - ruby-on-rails

How could you do what's covered in RyanB's Railscast on editing multiple records individually, using Formtastic? Formtastic doesn't use form_tag, which RyanB's method relies on.

The semantic_form_for is just a wrapper around form_for so you can use the same parameters. Here is a formtastic version of Ryan Bates' screencast
views/products/edit_individual.html.erb
<% semantic_form_for :update_individual_products, :url => update_individual_products_path, :method => :put do |f| %>
<% for product in #products %>
<% f.fields_for "products[]", product do |ff| %>
<h2><%=h product.name %></h2>
<%= render "fields", :f => ff %>
<% end %>
<% end %>
<p><%= submit_tag "Submit" %></p>
<% end %>
views/products/index.html.erb
<% semantic_form_for :edit_individual_products, :url => edit_individual_products_path do %>
<table>
<tr>
<th></th>
<th>Name</th>
<th>Category</th>
<th>Price</th>
</tr>
<% for product in #products %>
<tr>
<td><%= check_box_tag "product_ids[]", product.id %></td>
<td><%=h product.name %></td>
<td><%=h product.category.name %></td>
<td><%= number_to_currency product.price %></td>
<td><%= link_to "Edit", edit_product_path(product) %></td>
<td><%= link_to "Destroy", product, :confirm => 'Are you sure?', :method => :delete %></td>
</tr>
<% end %>
</table>
<p>
<%= select_tag :field, options_for_select([["All Fields", ""], ["Name", "name"], ["Price", "price"], ["Category", "category_id"], ["Discontinued", "discontinued"]]) %>
<%= submit_tag "Edit Checked" %>
</p>
<% end %>
Please note that you can use the form_for helpers as well in formtastic.
Update
If you like to use nested attributes as well it should work out of the box, using fields_for on the form partial. Lets stick with the railscast example and say that:
product.rb
has_many :commments
accepts_nested_attributes_for :comments
You can edit the comments on the _fields.html.erb of the products like:
<%= f.fields_for :comments do |cf| %>
<%=render 'comments/fields', :f=>cf%>
<%end%>
And make sure you have a fields partial in your comments views.

Related

Rails 5 edit multiple not showing values in table

I am creating multiple edit on my app. I have followed the revised Rails screencast and this code that adapts it to Rails 5.
In my Categories Controller:
def edit_multiple
#categories = Category.where(ID: params[:category_ids])
redirect_to categories_url
end
In my index:
<table class="table" summary="Category list">
<tr class="header">
<th style="text-align: left"><%= sort_link(#q, :NAME, 'NAME', default_order: :desc) %></th>
<th style="text-align: left">POSITION</th>
<th style="text-align: left">ACTIONS</th>
</tr>
<%= render "list" %>
</table>
<%= submit_tag "Edit Checked" %>
In my list partial:
<% form_tag edit_multiple_categories_path, method: :get do %>
<% #categories.each do |category| %>
<tr class="<%= cycle('odd', 'even') %>">
<td><%= check_box_tag "category_ids[]", category.ID %></td>
<td><%= link_to category.NAME, {:action => 'show', :ID => category.ID} %>
<td><%= category.RANK_POSITION %></td>
<td class="actions">
<%= link_to("Edit", {:action => 'edit', :ID => category.ID}, :class => 'button tiny') %>
<%= link_to("Delete", {:action => 'delete', :ID => category.ID}, :class => 'alert button tiny') %>
</td>
</tr>
<% end %>
<% end %>
When I open the categories page, it doesn't show anything from _list partial. There's only table headers and Edit Checked button.
Before adding the code relative to multiple edits the table was showing values from partial.
Note that db column names are capital as I'm building the app on existing db.
How can I fix it?
The problem was simply that
<% form_tag edit_multiple_categories_path, method: :get do %>
should be:
<%= form_tag edit_multiple_categories_path, method: :get do %>
I copied that from the railscast #165
Perhaps someone will find same issue and will find this useful.

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

Edit Multiple (reference Railscasts Episode #165)

I'm following Railscasts Episode #165 Edit Multiple but having issue where when I go to the product index page it is not showing my list of products. I'm getting only the header and the link to new product. Any idea what I did wrong?
By the way I'm using rails 3.2.3
Thank you.
routes.rb
resources :products do
collection do
post :edit_multiple
put :update_multiple
end
end
resources :categories
index.html.erb
<h1>Listing products</h1>
<% form_tag edit_multiple_products_path do %>
<table>
<tr>
<th></th>
<th>Name</th>
<th>Category</th>
<th>Price</th>
</tr>
<% for product in #products %>
<tr>
<td><%= check_box_tag "product_ids[]", product.id %></td>
<td><%= product.name %></td>
<td><%= product.category.name %></td>
<td><%= product.price %></td>
<td><%= link_to "Edit", edit_product_path(product) %></td>
<td><%= link_to "Destroy", product, :confirm => 'Are you sure?', :method => :delete %></td>
</tr>
<% end %>
</table>
<%= submit_tag "Edit Checked" %>
<% end %>
<p><%= link_to "New Product", new_product_path %></p>
You need <%= form_tag ... instead of <% form_tag .... Without the = the return value (i.e. your form) is discarded rather than added to the output.
I think this is typo.
you forgot to use "=" You should do <%= form_tag edit_multiple_products_path do %>

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

Ruby on Rails, Posting Variables

I'm very new to rails so hopefully this should be a quick fix. I'm writing an application that searches a database and reloads the page displaying the desired results. In rails how does one save a input into a text_field and post it so that it can be retrieved and used in the query for retrieving data.
My view:
<title></title>
</head>
<body>
Search Collection <br>
<%= text_field "person", "name" %>
<%= select_tag(:search_id, '<option value="0">Search by</option><option value="1">Make</option><option value="2">Condition</option>
<option value="3">Sport</option>') %>
<%= link_to 'New catalog', new_catalog_path %>
<br>
<br>
<%= link_to "Search", :search_text => , :action => :index %> <br>
<br>
<h1>Results</h1>
<%= will_paginate #catalogs %>
<table border="1">
<tr>
<th>Catalog id</th>
<th>Year</th>
<th>Make</th>
<th>Card number</th>
<th>Number</th>
<th>Condition</th>
<th>Sport</th>
<th>Tracking list</th>
</tr>
<% for catalog in #catalogs %>
<tr>
<td><%= catalog.Catalog_ID %></td>
<td><%= catalog.Year %></td>
<td><%= catalog.Make %></td>
<td><%= catalog.Card_Number %></td>
<td><%= catalog.Number %></td>
<td><%= catalog.Condition %></td>
<td><%= catalog.Sport %></td>
<td><%= catalog.Tracking_List %></td>
<td><%= link_to 'Show', catalog %></td>
<td>
<%= link_to 'Edit', edit_catalog_path(catalog) %></td>
<td>
<%= link_to 'Destroy', catalog, :confirm => 'Are you sure?', :method => :delete %></td>
</tr>
<% end %>
</table>
<br>
</body>
My Controller method
def index
#search_text = 'T206 White Border'
#catalogs = Catalog.paginate_by_sql ['select * from catalogs where Make =\''+ #search_text+'\'' , 80000], :page => params[:page]
end
Be gentle if its an easy fix, I'm still getting used to the whole MVC thing
Your question has a lot going on, so let's try to sort through it one piece at a time. First, I'll assume your database has a table called catalogs with a column called make, and that you're using the will_paginate plugin. It looks like you got started by copying and modifying some examples straight from the docs. First, your controller - you don't need the more complex paginate_by_sql, you can use the simpler paginate.
controller:
def index
#catalogs = Catalog.paginate(:all, :conditions => {:make => params[:search]}, :page => params[:page])
end
Now your view, just the stuff relevant to the search:
<% form_tag catalogs_path, :method => :get do %>
<%= text_field_tag 'search' %>
<%= submit_tag 'submit search' %>
<% end %>
And that's it. Good luck!

Resources