Forum: Ruby on Rails Modifying error_messages_for - I'm completely stuck

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
D5ca9a8e0973ac2a1871a53c6e67b0d8?d=identicon&s=25 Darren Evans (darrenevans2)
on 2007-07-02 19:07
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
Cd50d7d342c0d0bfef5c7e319ec1549b?d=identicon&s=25 Darren Evans (Guest)
on 2007-07-06 07:32
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
0900e6a4828bd989f96427082c6c74ca?d=identicon&s=25 Mike Garey (random52k)
on 2007-07-06 07:58
(Received via mailing list)
you can remove the prefix from the field name by using the
custom-err-msg plugin (http://rubyforge.org/projects/custom-err-msg/)

Mike
Cd50d7d342c0d0bfef5c7e319ec1549b?d=identicon&s=25 Darren Evans (Guest)
on 2007-07-06 08:15
Mike

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

Many thanks

Darren

Mike Garey 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
D5ca9a8e0973ac2a1871a53c6e67b0d8?d=identicon&s=25 Darren Evans (darrenevans2)
on 2007-07-07 10:58
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 Evans wrote:
> Mike
>
> Looks like excellent advice! I will give it a go!
>
> Many thanks
>
> Darren
>
> Mike Garey 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
D5ca9a8e0973ac2a1871a53c6e67b0d8?d=identicon&s=25 Darren Evans (darrenevans2)
on 2007-07-08 14:35
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
3f38541776a2513a20ea2f1c2d522cb3?d=identicon&s=25 Perry Smith (pedz)
on 2007-07-08 14:53
Darren Evans 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
D5ca9a8e0973ac2a1871a53c6e67b0d8?d=identicon&s=25 Darren Evans (darrenevans2)
on 2007-07-08 15:10
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 Smith wrote:
> Darren Evans 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
3f38541776a2513a20ea2f1c2d522cb3?d=identicon&s=25 Perry Smith (pedz)
on 2007-07-08 15:33
Darren Evans 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
This topic is locked and can not be replied to.