Changing Error Message in Rails Model - ruby-on-rails-3

I have a Rails (3.1) app with a model validation that, when triggered, puts the model and field name before the message, e.g.:
Profile image profile image content type Only jpeg, gif and png files are allowed for profile pictures
Is there a way to avoid that, so it reads:
Only jpeg, gif and png files are allowed for profile pictures
model.rb validation:
validates_attachment_content_type :profile_image,
:content_type => ['image/jpeg', 'image/png', 'image/gif'],
:message => "Only jpeg, gif and png files are allowed for profile pictures"
The error appears as a part of this code in my layout:
<% if object.errors.any? %>
<div class="alert alert-message error" data-alert="alert">
<a class="close" data-dismiss="alert">×</a>
<ul>
<% object.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>

My hunch is that msg is not actually the message but the entire error hash, and so calling <%= msg %> actually converts the whole hash to a string, including the keys. You could confirm this with <%= msg.class %>.
Assuming the view code you posted is a partial it would be helpful to see the view that includes the partial. If it's not a partial it would be useful to see the surrounding code.

Related

configure an existing controller to display devise notifications: undefined local variable or method `resource'

I have created a Rails 3 app with devise and i also have a controller called 'account' . When an user signs in with devise's sign in view , he's redirected to a view of account controller. So the notifications od devise "sign in successful" etc are not displayed. When i tried adding
<%= devise_error_messages! %>
to this view It gave an error
NameError in Account#welcome
undefined local variable or method `resource' for #<#:0x4e9fe70>
Can anyone pls tell me how to make this account controller display devise's notifications??
I tried reading the docs in github but didnt help..
I guess we have do modify routes file as its showing error in resources..
Update1:
Layout file:
<div id="maincontent">
<div class="entry">
<% flash.each do |name, msg| %>
<%= content_tag :section, msg, :id => "flash_#{name}", :class => "flash" %>
<% end %>
<!--<p class="commentbar"> Signup</p>-->
<%= yield %>
</div>
</div>
Once you installed Devise, there will be a block of guide. One paragraph is about the messages:
Ensure you have flash messages in app/views/layouts/application.html.erb.
For example:
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
So, to display success messages/notice, use
<%= notice %>
<%= alert %>
These two are also Rails default helper to show flash messages. So you are fine with both Devise and other normal flash messages with this setting.

Rails paperclip content type validation with client_side_validations

I am using paperclip for images. I want to make sure that only images files(jpeg/png) are uploaded.
Here is my paperclip validation rule.
validates_attachment :photo, :presence => { :message => "is required" }, :content_type => { :content_type => ['image/jpeg', 'image/jpg', 'image/png'], :message => "Invalid content type" }
The validation works and record is not saved if user uploads a non-image file. But the error message gets stored in #news.errors.messages[:photo_content_type] instead of #news.errors.messages[:photo]
I am using client-side-validations gem to display error messages. Since invalid content type message is attached to :photo_content_type, it is not displayed inline.
Right now I am displaying the message as follows:
<% if #news.errors.messages[:photo_content_type] %>
<div class="field_with_errors">
<%= f.file_field :photo %>
<label for="" class="validation-error-message">
<%= #news.errors.messages[:photo_content_type][0] %>
</label>
</div>
<% else %>
<%= f.file_field :photo %>
<% end %>
Is there a better way so that If user uploads a non image file, the message gets added to #news.errors.messages[:photo]
Update
I added after validation callback:
after_validation :join_img_errors
def join_img_errors
if errors.messages.has_key?(:photo_content_type)
errors.messages[:photo] = errors.messages[:photo_content_type]
end
end
This way, I don't have to modify view code. But I still have to add the callback to all the models that use paperclip.

undefined local variable or method `div' for #<#<Class:0x10923faf0>:0x109226b18>

I am having trouble with this as I get started with Ruby On Rails. Any help would be great. Additional info:
Extracted source (around line #25):
</header>
<div class="container">
<% flash.each do |key, value| %>
<%= content_tag(div, value, :class=> "alert alert-#{key}") %>
<% end %>
<%= yield %>
</div>
The line should be <%= content_tag(:div, value, :class=> "alert alert-#{key}") %>
Notice I'm passing in a symbol :div instead of just div. The error just means its trying to look for a variable or method named div but content tag accepts a symbol or string I believe. I think it will work with "div" as well.

Rails: Two separate create forms..how to keep them separate?

In Rails 3.0 I have the standard 'new' form that creates a new record, in this case a patient. It works fine and the validations / error showing also work fine.
The client now wants the form in Spanish.
So, I did this:
Created a new html doc called "newspanish" (Cut / paste code from "patients/new")
Created a new partial called "_form_newspanish" and referenced it where the "form" partial is in "newspanish" (Cut / paste code from view "patients/_form")
Created a controller action in "patients" called "newspanish" and cut/pasted exact code from the "new" action.
I left the "create" action untouched.
Added match "patients/newspanish" to routes.
Translated the english parts to spanish in views/newspanish and views/_form_newspanish. Just the stuff that users read on the page, of course...not the rails code.
And, it works, for perfect submissions.
For submissions that fail validation (like putting 3 digits in as a phone number), the page reverts to the view "patients/new" and shows the errors above the form... in English, of course, because patients/new is in English.
Of course, I want it to revert to "views/newspanish" and also show custom verbage in the validations errors (spanish).
Any thoughts on how I can get the patients/newspanish view to load when error validation it tripped?
Here's my code for "_form_newspanish"
<%= form_for(#patient) do |f| %>
<% if #patient.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#patient.errors.count, "error") %> prohibited this subscriber from being saved:</h2>
<ul>
<% #patient.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p><label for="mobile">Número de teléfono celular o móvil*</label>: <%= f.text_field :mobile %></p>
<br />
<%= f.submit "Inscribirme" %>
</div>
<% end %>
And controller... patients/newspanish
def newspanish
#patient = Patient.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #patient }
end
end
<%= form_for(#patient) do |f| %>
is creating a form whose url is submits to is "/patients" which matches to patients_controller, create action.
That create action probably has a line that says (in my pseudo code)
if #patient.save
redirect to somewhere
else
render :new
end
That line "render :new" is showing the "patients/new" view.
So what you have to figure out is to either
1) detect in patients_controller # create how to tell if its spanish, and render "newspanish"
OR
2) change <%= form_for(#patient) do |f| %> to submit to a new url that just handles the spanish version, and make a new controller or action that just handles the spanish form (and renders "newspanish" if the #patient doesn't save
For #2, you could manually change where the form submits to with
<%= form_for(#patient), :url => spanish_patients_path do |f| %>
and in your routes create
post "patients/spanish" => "patients#create_in_spanish"
and add def create_in_spanish to your patients controller

Interaction between controllers

On my web app I have a login page which is in the Pages Controller called welcome.html.erb
Inside it has a simple form for login and a simple for for sign up, both on the same page.
If the user signs up with wrong credentials (like password confirmation wrong, or length of password and etc) the controller that handles this is the new method in the Users Controller.
Inside the new method it checks if a user is created, and if not I'd like it to return to the welcome method in Pages Controller, passing to it the errors that were created during the user's creation.
It seems that if I do a
redirect_to root_path
The error count of the signup is reset when returning to the root page. If instead I call some other action of the users controller I do see the errors.
But since all of the html code is in the welcome view I don't want to replicate the code in the users controller views as well..
Is there a way to pass that errors data to the pages controller?
The partial for the error is
<% if object.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(object.errors.count, "error") %> prohibited this <%= object.class.to_s.underscore.humanize.downcase %> from being saved:</h2>
<p>There were problems with the following fields:</p>
<ul>
<% object.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
Which I call using
<%= render 'shared/error_messages', :object => f.object %>
redirect_to welcome_path
(Or whatever the actual path is.)
From the Users controller I called
flash[:errors]=#user.errors
and then I changed the partial to be
<% if object.any? %>
<div id="error_explanation">
<h2><%= pluralize(object.count, "error") %> prohibited this <%= object.class.to_s.underscore.humanize.downcase %> from being saved:</h2>
<p>There were problems with the following fields:</p>
<ul>
<% object.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
Which I called using
<%= render 'shared/error_messages', :object =>#user_errors %>
That solved the issue for now..