Forum: Ruby on Rails How to use validation with aggregation (composed_of)?

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.
Db17235590f0dba6564d02d445e84ad1?d=identicon&s=25 Simon Harris (Guest)
on 2005-12-17 01:47
(Received via mailing list)
At the risk of being banned for posting the same question twice, I
thought I'd try once more with a question for the title rather than a
statement (on the basis that perhaps questions get answered and
statements ignored ;-) )

ActiveRecord supports composed_of for value objects which is
fantastic but one thing that it doesn't seem to support (or at least
I am unable to find any documentation for) validation of the value
objects.

For example, given the following:

class Message < ActiveRecord::Base
	composed_of :sender, :class_name => 'EmailAddress'
	composed_of :recipient, :class_name => 'EmailAddress'
	...
end

class EmailAddress
	attr_reader :name, :address
	def initialize(name, address)
		@name, @address = name, address
	end
	...
end

How can I best take advantage of Rails' validation, given that I'd
like to only specify the validation rules for EmailAddress once. The
validation rules might look something like:

	validates_presence_of :name, :address
	validates_format_of :email, :with => ADDRESS_FORMAT

I'm guessing the obvious answer is to create an email_addresses table
and use belongs_to but that seems (to me at least) a somewhat heave-
handed approach.

Regards,

Simon

--
Simon Harris
RedHill Consulting, Pty. Ltd.
12/55-67 Batman Street
West Melbourne VIC Australia 3003
http://www.redhillconsulting.com.au
mob: +61 417 505 611
yahoo/msn/skype: haruki_zaemon
gmail: haruki.zaemon
icq: 20461518
C64e63b70be7dfed8b0742540b8b27e5?d=identicon&s=25 Mark Reginald James (Guest)
on 2005-12-17 05:29
(Received via mailing list)
Simon Harris wrote:

> ActiveRecord supports composed_of for value objects which is  fantastic
> but one thing that it doesn't seem to support (or at least  I am unable
> to find any documentation for) validation of the value  objects.

Here's an attempt at a solution.  Any better way?

class Message < ActiveRecord::Base
   composed_of :sender, :class_name => 'EmailAddress',
               :mapping => [[:sender_name], [:sender_address]]

   composed_of :recipient, :class_name => 'EmailAddress',
               :mapping => [[:recipient_name], [:recipient_address]]

   def validate
     ['sender', 'recipient'].each do |attr|
       obj = self.send(attr)
       ['name', 'address'].each do |field|
         msg = obj.send("valid_#{field}?")
         # choose one of the following
         errors.add_to_base( "#{attr}'s #{field} #{msg}" ) unless
msg.blank?
         errors.add( "#{attr}_#{field}", msg ) unless msg.blank?
       end
     end
     super
   end
end

class EmailAddress
   attr_reader :name, :address

   def initialize( name, address )
     @name, @address = name, address
   end

   def valid_address?
     @valid_address ||=
       check_valid?( @address ) ? '' : 'is not a valid email address'
   end

   def valid_name?
     @valid_name ||=
       if @name.blank?
         'cannot be blank'
       elsif @name =~ /[A-Za-Z][A-Za-z -]*/
         ''
       else
         'contains invalid characters'
       end
   end
end

--
We develop, watch us RoR, in numbers too big to ignore.
This topic is locked and can not be replied to.