Ruby method to remove accents from UTF-8 international characters
I generally use I18n to handle this:
1.9.3p392 :001 > require "i18n"
=> true
1.9.3p392 :002 > I18n.transliterate("Hé les mecs!")
=> "He les mecs!"
How to show nested form validation errors after the validation errors for the parent model?
Update 1:
I discovered that the answer by februaryInk was very close to correct if you don't need to worry about i18n and translation of your application text. If you put the has_many :child_model
underneath all your validations, the validations will appear in the correct order. However, full_messages
doesn't appear to translate model or attribute names using the locale files, so if you require the error messages to be translated (which I do), my answer still seems like a decent solution.
Update 2:
Just realized after posting the first update that I could simplify my code that generates the messages
list a lot by removing the part that does the ordering using the discovery in update 1, and just keep the part that does the translation. So here is my new solution, which is a combination of my update 1 and my original solution. All other information about the config/locales/xx.yml
and config/application.rb
files is still the same for this updated solution as it was for the original.
app/models/parent_model.rb
...
validates :name, # validations hash
validates :description, # validations hash
validates :others, # validations hash
has_many :child_models
accepts_nested_attributes_for :child_models
...
app/models/child_model.rb...
validates :nested_1, # validations hash
validates :nested_2, # validations hash
...
app/helpers/application_helper.rbmessages = resource.errors.messages.keys.map {|value| error_message_attribute(resource, value) + I18n.t('space') + resource.errors.messages[value].first}.map { |msg| content_tag(:li, msg) }.join
private
def error_message_attribute(resource, symbol)
if symbol.to_s.split(".").length > 1
model_name, attribute_name = symbol.to_s.split(".")
model_class = model_name.singularize.camelize.constantize
model_class.model_name.human + I18n.t('space') + model_class.human_attribute_name(attribute_name).downcase
else
resource.class.human_attribute_name(symbol)
end
end
End of UpdateI made a few changes to my error_messages
function in application_helper.rb
and now have everything working the way I wanted: main form validation errors are on the top, nested form validation errors are under those, the order of the errors does not change except moving the nested form errors under the main form errors.
My solution was to change the messages =
line in error_messages
as shown below and to add a private helper method. (This should probably be broken down into parts to make it easier to read and understand, but I built it up in the console to get what I wanted and just pasted it directly from there).
app/helpers/application_helper.rb
messages = Hash[resource.errors.messages.keys.map.with_index(1) { |attribute, index| [attribute, [index, attribute.match(/\./) ? 1 : 0]] }].sort_by {|attribute, data| [data[1], data[0]]}.collect { |attributes| attributes[0]}.map {|value| error_message_attribute_name(resource, value) + I18n.t('space') + resource.errors.messages[value].first}.map { |msg| content_tag(:li, msg) }.join
private
def error_message_attribute_name(resource, symbol)
if symbol.to_s.split(".").length > 1
model_name, attribute_name = symbol.to_s.split(".")
model_class = model_name.singularize.camelize.constantize
model_class.model_name.human + I18n.t('space') + model_class.human_attribute_name(attribute_name).downcase
else
resource.class.human_attribute_name(symbol)
end
end
This solution should also work for other other locales, since I used I18n
to get all the names. You will have to add the following also:config/locales/en.yml
en:
space: " "
This is so the model and attribute names will be handled correctly in languages that either have or don't have spaces between words (the first locale I need to support is Chinese, which doesn't have spaces between the words). If you did need to support Chinese, for example, you would use this:config/locales/zh.yml
zh:
space: ""
If you don't have to support this case, all instances of I18n.t('space')
can be replaced with " "
. The model and attribute names can also be translated as, but again if you don't need to support locales beyond English you don't need to do anything (although you can use the en.yml
file to change the names of the model or attributes that are displayed).As an example using en.yml
to change the names displayed using the common Authors/Books example:
config/locales/en.yml
en:
activerecord:
models:
author: "writer"
book: "manuscript"
attributes:
author:
name: "non de plume"
book:
name: "title"
published: "year"
In this example the default, without the above additions to en.yml
, would be:- Name can't be blank.
- Book name can't be blank.
- Book published can't be blank.
en.yml
it would be:- Nom de plume can't be blank.
- Manuscript title can't be blank.
- Manuscript year can't be blank.
zh.yml
file with the appropriate translations, whatever you have in those would show up instead.If you do need to support multiple locales, don't forget to add the following to config/application.rb
(this part was only tested superficially, and may need some additional configuration):
config/application.rb
config.i18n.available_locales = [:zh, :en]
config.i18n.default_locale = :en
Create a helper or something for haml with ruby on rails
You can use haml_tag too
def content_box
haml_tag :div, :class => "holder" do
haml_tag :div, :class => "top"
haml_tag :div, :class => "content" do
yield
haml_tag :div, :class => "bottom"
end
end
and in haml%html
%head
%body
Maybee some content here.
= content_box do
Content that goes in the content_box like news or stuff
Rails controller fails with TypeError - Error during failsafe response?
It turns out that the problem was that the line
token=RegistrationManager.get_instance.get_auth_token(params)
which refers to a helper class called RegistrationManager that I had in the helpers subdirectory. For reasons I still dont understand, if you refer to a class rather than module that lives in the helpers directory, Rails is unhappy. Why it fails at line 1, I'm not really sure, but moving the class out of helpers into controllers/concerns solved the problem. I wish the error messaging referred to the location of the bad call rather than at line 1, could have saved me and Mr. Adel a lot of time!
Related Topics
Rails 3, Http Extensions (Webdav) and Rack App Mounting
Ruby Gem Development - How to Use Activerecord
How to Send an Image on The Web in an Xmpp (Jabber) Message
How to Directly Install a Gem from a Git Repository
Rails Redirecting Invalid Route to Root
Require Tree in Asset Pipeline
How Do Erlang Actors Differ from Oop Objects
How to Validate Overlapping Times in Rails with Postgresql
Reading Files in a Zip Archive, Without Unzipping The Archive
Filtering Sensitive Data with Vcr
Ruby Rspec. Get List of All Test
Overriding Instance Variable Array's Operators in Ruby
How to Create Thor::Group Generators as Args of My_Command
How to Make Devise Registrationscontroller to Show Sign_Up Page Only If User Is Already Signed In
Rails 3.1 Has_One Nested Resource: Routing Not Generating "All" Paths
How to Resize Image Only If Width Exceeds with Graphics/Image Magick
Shellwords.Shellescape Implementation for Ruby 1.8
Getting a "Connection Reset by Peer" Error When Hitting Google Contacts API