Get validation errors on a partial's form - ruby-on-rails

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

Related

How to save form data in rails dynamically

I have a form that users enter data in, with a button to save the data. The form also has buttons to send the user to other forms to enter more info.
<%= form_with(model: [order_header], local: true) do |f| %>
<%= render "shared/errors", object: order_header %>
<%= f.hidden_field(:customer_id, value: #customer.id) %>
<%= f.label :status %>
<%= f.select(:status, [['Quote', 1], ['Order', 3], ['Invoice', 5]]) %>
<%= f.label :customer_purchase_order %>
<%= f.text_field :customer_po %>
<h4>Lines</h4>
<table cellpadding=10>
<% #orderlines = order_header.order_lines %>
<% #orderlines.each do |line| %>
<tr>
<td><%= line.line_type %></td>
<td><%= line.description %></td>
<td><%= link_to 'Edit', edit_design_item_path(line.design_item_number), class: "inline_button" %></td>
<% end %>
</tr>
</table>
<section class="button-bar">
<%= f.submit "Save", class: "button" %>
</section>
<% end %>
If the user hits an 'Edit' button, before hitting the 'Save' button, the data entered on the main form is lost. Is there a way to automatically save the data on the main form before calling the other form via the edit button?

Rails form_for only submitting last input

Im trying to create inputs by looping each product and have one form submission for all the inputs. Currently, the form only submits the last input. How would I make it so all the inputs get submitted?
<%= form_for :inventory do |f| %>
<% #products.each do |product| %>
<tr>
<td><%= product.name %></td>
<td><%= product.measurement %></td>
<td><%= f.number_field :amount, class: 'form-control' %></td>
<%= f.hidden_field :product_id, :value => product.id %>
</tr>
<% end %>
<%= f.submit %>
<% end %>
I dont know your use case but you can use the gem cocoon for doing that. There will also be a link to add/remove another product.
https://github.com/nathanvda/cocoon
You can iterate with each_with_index:
<%= form_for :inventory do |f| %>
<% #products.each_with_index do |product, i| %>
<tr>
<%= f.hidden_field "product_id[#{i}]", :value => product.id %>
</tr>
<% end %>
<%= f.submit %>
<% end %>
Like that the output is not very elegant (something like "product_id"=>{"0"=>"1", "1"=>"2", "2"=>"3"... }) but it's for the example to show how every hidden field needs a unique key.
You can define your params in a better way to use them in the controller, just keep them unique.

Rails 3.1 multiple objects on one form

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

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

Rails 3 - How to comment in a View?

What is the Rails 3 way to comment out One Line or Multiple lines of code in a View? And so it doesn't show up in the HTML Source
To comment out a single line ob ruby code use
<%# code %>
or for multiple lines
<%
=begin
your code
=end
%>
EDIT:
Here a example to comment out a loop in an view.
The =begin and =end must stand directly at the beginning of the line.
There couldn't be any spaces or tabs.
<h1>Listing posts</h1>
<table>
<tr>
<th>Title</th>
<th>Text</th>
<th></th>
<th></th>
<th></th>
</tr>
<%
=begin
%>
<%#posts.each do |post| %>
<tr>
<td><%= post.title %></td>
<td><%= post.text %></td>
<td><%= link_to 'Show', post %></td>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
<td><%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %></td>
</tr>
<% end %>
<%
=end
%>
</table>
Rails 3 line comment within a view:
The f.label :name line has been commented out:
<%= form_for(#usr) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%#= f.label :name %>
<%= f.text_field :name %>
<%= f.submit "Save changes" %>
<% end %>
Because this is a view, the # must be within <% and %>.
Rails 3 multi-line comment within a view:
Begin multi-line comment:
<%
=begin
%>
End multi-line comment:
<%
=end
%>
Below, the entire form_for block has been commented out:
<%
=begin
%>
<%= form_for(#usr) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.submit "Save changes" %>
<% end %>
<%
=end
%>
Do take note, for the multi-line comment tags to work, there can be no spaces or tabs in front of =begin or =end. They need to be at the very beginning of a line, or they will not work.
Here's what I do to hide comments from HTML (...whatever, it works!)
in your helpers/application.rb file:
def comment
# use this keyword in the views, to comment-out stuff...
end
in your view:
<h3><% comment = "my Rails-y something something here will not be visible to HTML.
I don't know why I have to comment stuff out in this manner.
It's probably not the 'Rails Way' but ...it works for me.
It would be nice if Rails 3 had some kind of comment-out feature like <%## %> or <%-- --%> or something like that...
Ah, well...
At least they won't be able to 'View Source' and read this comment! ;]
" %></h3>
what 'View Source' shows:
<h3></h3>
C-YA!
Some ways to comment code
<%
=begin
%>
RUBY CODE GOES HERE
<%
=end
%>
<% if false %>
RUBY CODE GOES HERE
<% end %>
<%# RUBY CODE%>
<%#= RUBY CODE%>
<!--
HTML CODE
-->
For RUBY code in.rb files like models/controllers
def xyz
=begin
blah blah code
=end
end
For JS etc
/*
Some code
*/
which "blocks" do you mean?
html? then you can use
ruby code? <%# code %>

Resources