Modifying error_messages_for - I'm completely stuck


#1

To cope with languages other than English, it seems to be necessary to
modify error_messages_for by defining a new application helper. Tricky
stuff for a novice like me!

I need to get all of the text out so that I can make it language
dependent. I have used instance variables at the moment, but will get
them out of the helper once I have a solution. The problem I have is
with the error lines such as the following, which contain a field name
as a prefix:

Terms : You must accept the Terms and Conditions

The following regular expression should work on the above line I think
(i.e. to get rid of “Terms :” so that all remains is the message passed
from the validation :message in the model

[A-Za-z0-9| ]*$

So I am trying to do the following to a line near the bottom of the
script

        error_messages = objects.map {|object|

object.errors.full_messages.map {|msg| content_tag(:li, /[A-Za-z0-9|
]*$/.match(msg)) } }

I am obviously making a mistake here, because it gives nothing except a
bullet point, but I am not sure what. Does anyone have an idea where I
am going wrong?

Any help would be really appreciated.

Darren

def my_error_messages_for(*params)
@e1=‘There were problems with the following fields:’
@e2=‘errors’
@e3=‘prohibited this from being saved’
options = params.last.is_a?(Hash) ? params.pop.symbolize_keys : {}
objects = params.collect {|object_name|
instance_variable_get("@#{object_name}") }.compact
count = objects.inject(0) {|sum, object| sum +
object.errors.count }
unless count.zero?
html = {}
[:id, :class].each do |key|
if options.include?(key)
value = options[key]
html[key] = value unless value.blank?
else
html[key] = ‘errorExplanation’
end
end

         header_message = "#{pluralize(count, @e2)} #{@e3}"
        error_messages = objects.map {|object|

object.errors.full_messages.map {|msg| content_tag(:li, msg) } }
content_tag(:div,
content_tag(options[:header_tag] || :h2, header_message)
<<
content_tag(:p, @e1) <<
content_tag(:p, error_messages),
html
)
else
‘’
end
end
end


#2

It’s 3 days later and I have not had a reply yet. I have still not made
any progress. I hope that someone can help me a little with this.

Thanks

Darren


#3

you can remove the prefix from the field name by using the
custom-err-msg plugin (http://rubyforge.org/projects/custom-err-msg/)

Mike


#4

Mike

Looks like excellent advice! I will give it a go!

Many thanks

Darren

Mike G. wrote:

you can remove the prefix from the field name by using the
custom-err-msg plugin (http://rubyforge.org/projects/custom-err-msg/)

Mike


#5

This part works, but now I have problems with variables in models
associated with this. How can I get @message1 to @message13 out of the
model so that I can define them using a database query? I have a session
variable called language_id which defines the language, but I can’t
access it from the model of course. I would like to pass the variables
to the model, but how can I do that when the code is not within a
def…end?

Thanks!

require ‘digest/sha1’
class User < ActiveRecord::Base
require_dependency “search”

searches_on :firstname, :lastname, :formally_known_as
has_many :friends, :dependent => :destroy
has_many :logins, :dependent => :destroy
has_many :usercategories, :dependent => :destroy
has_many :userimages, :dependent => :destroy
has_many :usernotifications, :dependent => :destroy
has_many :userplaces, :dependent => :destroy

has_many :sent_messages, :class_name => “Message”, :foreign_key =>
“sender_id”, :order => ‘created_at DESC’
has_many :received_messages, :class_name => “Message”, :foreign_key =>
“recipient_id”, :conditions => [‘deleted_at IS NULL’], :order =>
‘created_at DESC’
has_many :unread_messages, :class_name => “Message”, :foreign_key =>
“recipient_id”, :conditions => [‘read_at IS NULL AND deleted_at IS
NULL’], :order => ‘created_at DESC’

@message1="^You must enter your first name."
@message2="^You must enter your last name."
@message3="^You must enter your email address."
@message4="^Your username must be at least 6 characters long."
@message5="^Someone with your username is already registered with us,
please choose another."
@message6="^You must enter a username."
@message7="^Your e-mail address is already registered with us. Please
select the ‘forgot password’ link on login box to be resent your
username and password."
@message8="^You must enter a password."
@message9="^Your e-mail address is not a valid format."
@message10="^Your password must be at least 6 characters long."
@message11="^You must enter confirmation of your password."
@message12="^Your password and confirmation were not the same."
@message13="^You must accept the Terms and Conditions to register."

validates_presence_of :firstname, :message => @message1
validates_presence_of :lastname, :message => @message2
validates_presence_of :email, :message => @message3
validates_length_of :username, :minimum => 6, :message => @message4
validates_uniqueness_of :username, :message => @message5
validates_presence_of :username, :message => @message6
validates_uniqueness_of :email, :message => @message7
validates_presence_of :password, :on => :create, :message =>
@message8
validates_format_of :email, :message => @message9, :with =>
/^([^@\s]+)@((?:[-a-z0-9]+.)+[a-z]{2,})$/i
validates_length_of :password, :minimum => 6, :message => @message10,
:on => :create
validates_presence_of :hashed_password, :on => :create, :message =>
@message11
validates_confirmation_of :password, :on => :create, :message =>
@message12
validates_acceptance_of :term, :on => :create, :message => @message13

attr_accessor :password_confirmation

Darren E. wrote:

Mike

Looks like excellent advice! I will give it a go!

Many thanks

Darren

Mike G. wrote:

you can remove the prefix from the field name by using the
custom-err-msg plugin (http://rubyforge.org/projects/custom-err-msg/)

Mike


#6

Has anyone come across this before? How can I pass variables to
validates… in a model, the problem being that it is at the first
level and I cannot use session variables.

Darren


#7

Thanks, I’ll take a look there and can hopefully find something there. I
wasn’t aware of this forum.

Just so that I understand properly, the answer to my previous question
is “no, because it is against the ROR philosophy”. Is that right?

Darren

Perry S. wrote:

Darren E. wrote:

Has anyone come across this before? How can I pass variables to
validates… in a model, the problem being that it is at the first
level and I cannot use session variables.

Darren,

Look at this forum:

http://www.ruby-forum.com/forum/20

It is called “Ruby I18N” which should be exactly the place for you.

Good luck


#8

Darren E. wrote:

Has anyone come across this before? How can I pass variables to
validates… in a model, the problem being that it is at the first
level and I cannot use session variables.

Darren,

Look at this forum:

http://www.ruby-forum.com/forum/20

It is called “Ruby I18N” which should be exactly the place for you.

Good luck


#9

Darren E. wrote:

Just so that I understand properly, the answer to my previous question
is “no, because it is against the ROR philosophy”. Is that right?

I honestly am not the best person to ask. I notice a few things. You
are passing instance variables. I don’t know how the validates_…
things work but since they are out side of any execution path, I would
assume they set up something at load time. This is way before any
instances have been created. I’m surprised it works really.

You could give it @@variable – class variables. These will stay put.
Then, somehow, magically make the @@variable point to an @variable that
will change based upon the users language. There are all sorts of hooks
– maybe put that into before_validate.

But, I would try to go for some table driven solution. (This may be
what you are trying to do after you get something – anything –
working.) An array of an array of string. Where the first index is the
language (could be a hash), the second index is a message number (or a
hash).

And, my other thought, while validates_… are easy, you can put all
this into a validate method. At that point, you have the instance
context.

This is documented in callbacks.rb but you have all these hookds:

* (-) save

* (-) valid?

* (1) before_validation

* (2) before_validation_on_create

* (-) validate

* (-) validate_on_create

* (3) after_validation

* (4) after_validation_on_create

* (5) before_save

* (6) before_create

* (-) create

* (7) after_create

* (8) after_save

(and many others if this is an updates or a delete).

Good luck