Display error messages in rails simple_form - ruby-on-rails-3

I am new to rails and was wondering if someone could show me some light...
I have a simple form with couple of input fields and need to display field validation messages below the field name. Is there is a straightforward way to say display errors below??? or do i have to check for each field error message and create a span tag?

You can specify in your simple_form.rb initializer file with which tag your error message will be wrapped:
b.use :error, :wrap_with => { :tag => :span, :class => :error }
Also you can disable default error component on the input and print it by yourself like this:
<%= simple_form_for #user do |f| %>
<%= f.input :name, error: false %>
<%= f.error :name %>
<%= f.submit %>
<% end %>
and style your error message like you want.

Related

undefined method `model_name' in a partial rendered by different controller

I'm trying to render this form:
<form class="form-inline">
<%= simple_form_for #prospect,
:url => url_for(:action => 'create', :controller => 'prospects'),
:method => 'post' do |f| %>
<%= f.error_notification %>
<%= f.input :name, placeholder: 'Name', label: false %>
<%= f.input :email, placeholder: 'Email', label: false %>
<%= f.input :interests, placeholder: 'Tell us what you were searching for', label: false, value: params[:search] %>
<%= f.error :base %>
<%= f.button :submit, "Submit", :class=> "btn" %>
<% end %>
Using this partial:
<%= render partial: 'prospects/novideo_capture' %>
The partial is in a view controlled by Videos#index controller, and I keep getting this error: 'undefined method `model_name' for NilClass:Class'
This is my prospects controller:
class ProspectsController < ApplicationController
def index
#prospects = Prospect.all
end
def new
#prospect = Prospect.new
end
def create
#prospect = Prospect.new(params[:prospect])
if #prospect.save
render "thanks_for_interest"
else
render "novideo_capture"
end
end
I'm not sure what I'm going wrong, although I'm pretty sure it's a simple solution. I've seen a lot of similar questions around SO and tried all their answers, but none of them seem to work for this situation.
Thanks for any help...
EDIT: Adding
#prospect = Prospect.new
to the videos index controller stops the error occurring, but I don't feel it's the right way to do this. It also doesn't actually make the form use the prospects controller.
EDIT2: I now have the partial rendering correctly (I think), and my videos#index calls the partial like this:
<%= render partial: 'prospects/novideo_capture', :prospect => #prospect %>
Then simple_form in the partial looks like this:
<form class="form-inline">
<%= simple_form_for :prospect,
:url => url_for(:action => 'create', :controller => 'prospects'),
:method => 'post' do |f| %>
...
<% end %>
However it's not actually submitting the form with the prospects controller. Any ideas why?
Check your markup. You're wrapping a simple_form inside another form. Since the first form tag has no action associated with it (<form class="form-inline">), that form will submit against the current URL, which is the video#index.
You're going to want something like this:
<%= simple_form_for :prospect, :url => etc, :method => 'post', :class => "form-inline" do |f|
...
<% end %>
Losing the leading (redundant) form-inline form tag and you'll be fine.

Simple_form - How to add field name to error messages?

I have tweaked the bootstrap wrapper so that now I display all inline errors as a block above the simple_form field.
The form is a registration Devise form, specifically from the rails-prelaunch-signup composer app. How can I include the name of the field in the error message?
At the moment I am getting "isn't valid" or "can't be blank", however I would like something like "Email can't be blank".
Simpleform refers to rails localization if no error message is set in the model. So, if you want to add the attributes name to each error message, you could add something like this in your locale-file:
en:
errors:
messages:
blank: "%{attribute} can't be blank"
invalid: "%{attribute} isn't valid"
Where %{attribute} is the placeholder where the fields name will be inserted.
You can set the error message in the model:
validates :email, presence: { error_message: "Email can't be blank" }
To add the attribute name on every error message, you can use the full_error helper instead of the classic error helper
Directly in your form
<%= simple_form_for #user do |f| %>
<%= f.label :username %>
<%= f.input_field :username %>
<%= f.full_error :username %>
<%= f.submit 'Save' %>
<% end %>
Or in your custom wrappers
# config/initializers/simple_form.rb
SimpleForm.setup do |config|
# ...
config.wrappers :vertical_form do |b|
# ...
b.use :label
b.use :input
b.use :full_error
end
end

Weird undefined method 'all' and collection_select error

I've got a form like this (simplified, but you get the idea):
<%= form_for(#brand, :html => { :class => "form-horizontal" }) do |f| %>
<%= f.fields_for :prices do |price| %>
<%= price.collection_select(:price, :template_id, Template.all, :id, :name) %>
<% end %>
<%= f.submit "Save", :class => 'btn btn-primary' %>
<% end %>
Which when rendered gives me this error
undefined method `all' for ActionView::Template:Class
on the collection_select line.
Template.all works from the controller and the console. If I write a #templates = Template.all and use #templates in the collection_select line then I get this error:
undefined method `merge' for :name:Symbol
Any thoughts?
You can do it by prefixing with two colon. e.g,
<%= price.collection_select(:price, :template_id, ::Template.all, :id, :name) %>
but I believe, you should avoid using Template as model name as it is rails Action View Template
Solved it. It was annoyingly simple.
<%= price.collection_select(:template_id, #templates, :id, :name) %>
Duplication. Eugh.

Add message to formtastic semantic error block

If there are semantic errors in the form (mostly from external API), I'd like to add an explanatory message, like so:
<%= semantic_form_for #order, :url => checkout_purchase_url, :html => {:class => 'payment'}, :wrapper_html => { :class => "field" } do |f| %>
<% if f.has_errors? %>
<p>There were errors that prevented your order from being submitted. If you need assistance, please contact us toll-free at <strong>1-800-555-5555</strong>.</p>
<%= f.semantic_errors %>
<% end %>
<% end %>
However, has_errors? is a protected method. Is there a way that I can do this? Thanks.
If you have nested attributes you won't see any errors associated with them. To ensure you get all base errors and any nested attributes errors. Make sure your model contains:
validates_presence_of :nested_object
validates_associated :nested_object
and in your form:
f.semantic_errors *f.object.errors.keys
Not as hard as I thought. I fixed it by checking for errors on the object instead of the form:
<% if #object.errors.any? %>
<p>There were errors that prevented your order from being submitted. If you need assistance, please contact us toll-free at <strong>1-800-555-5555</strong>.</p>
<%= f.semantic_errors %>
<% end %>
Thanks for those who viewed.
For completeness, here's an alternative approach if you want to show similarly helpful messages on each field:
= f.label :title
- if f.object.errors.any?
.error = f.object.errors[:title].flatten.join(' and ')
= f.text_field :title
This gives a nicely formatted and easily-styled list of errors for each field. (You can use semantic_errors instead of object.errors if you prefer, same result.)

Rails appends id to singular route when render edit after errors

I have the following singular route:
scope '/seller' do
resource :seller_profile, :path => "/profile", :only => [:show, :edit, :update]
end
and the following controller:
class SellerProfilesController < ApplicationController
before_filter :validate_user_as_seller
def show
#seller_profile = current_user.seller_profile
end
def edit
#seller_profile = current_user.seller_profile
end
def update
#seller_profile = current_user.seller_profile
if #seller_profile.update_attributes(params[:seller_profile])
redirect_to(seller_profile_path, :notice => 'Profile was successfully updated.')
else
render :action => "edit"
end
end
end
I use a singular route given that the user must be authenticated before gaining access to the controller and therefore I can get the seller_profile from the user logged in.
This works like a charm, with only one problem. When I edit the seller_profile and validation error happen, the form is edited again and the errors are displayed correctly. The problem is that rails appends to the url the id of the edited record. For instance,
when I first edit the record, the url is:
http://0.0.0.0:3000/seller/profile/edit
but if the form is submitted with validation errors, the form itself is redisplayed under
http://0.0.0.0:3000/seller/profile.2
where 2 is the ID of the record being edited.
The form is the following:
<%= simple_form_for #seller_profile do |f| %>
<%= f.input :name %>
<%= f.input :description %>
<%= f.submit %>
<% end %>
Everything, as said, works great but I would totally mask the ID in the url. What should I do?
I have not really worked too much with simple_form_for. But it looks like it is guessing your url always as if they were not single resources. You can provide a custom one:
<%= simple_form_for #seller_profile, :url => seller_profile_path do |f| %>
<%= f.input :name %>
<%= f.input :description %>
<%= f.submit %>
<% end %>