Validates_exclusion_of


#1

I am writing a very simple personal expenses calculator. each expense
aka dealing can be of the type:

dealing name: albertsons
payer : deepak
recievers : akash,sid
amt : 15 USD

so akash and sid each owe me 5 USD each. many such dealings and at the
end of the mth or so you can find out how much you are in credit/debit.

now…my defintions are:
– every dealing can have one and only one payer
– every dealing can have many receivers

Models consist of: Dealing,Party(represents both payer and receiver) and
Money(reps 15,USD)

and my dealing class looks like this:

class Dealing < ActiveRecord::Base
belongs_to :payer, :class_name => “Party”, :foreign_key => “payer_id”
has_and_belongs_to_many :receivers,:class_name => “Party”, :join_table
=> “receivers”, :association_foreign_key => “party_id”
composed_of :money, :mapping => [[:amount, :amount],[:currency,
:currency]]

validates_presence_of :name,:occured_on,:payer,:receivers,:amount

validates_numericality_of :amount

validates_exclusion_of :payer,:in => :receivers, :message => “Payer is
also same as receiver”

validates_each :receivers do |record,attr,value|
record.errors.add attr,‘are repeated’ if value.uniq.size != value.size
end

def amt_per_head
if payer_inclusive == ‘Y’
Money.new(money.amount / (receivers.size + 1))
else
Money.new(money.amount / receivers.size)
end
end

def validate
errors.add “Payer is same as receiver! Either” if receivers.include?
payer
end

protected :validate

This validation:

validates_exclusion_of :payer,:in => :receivers, :message => “Payer is
also same as receiver”

fails and this is what irb tells me::

D:\rubywork\projects\rails\ezexpense>ruby script/console
Loading development environment.

deal = Dealing.new
ArgumentError: An object with the method include? is required must be
supplied a
s the :in option of the configuration hash
from
d:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.11.1/lib/active_recor
d/validations.rb:551:in validates_exclusion_of' from ./script/../config/../app/models/dealing.rb:10 from d:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.1.1/lib/active_suppo rt/dependencies.rb:193:inload’
from
d:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.1.1/lib/active_suppo
rt/dependencies.rb:193:in load' from d:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.1.1/lib/active_suppo rt/dependencies.rb:38:inrequire_or_load’
from
d:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.1.1/lib/active_suppo
rt/dependencies.rb:21:in depend_on' from d:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.1.1/lib/active_suppo rt/dependencies.rb:171:inrequire_dependency’
from
d:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.1.1/lib/active_suppo
rt/dependencies.rb:171:in require_dependency' from d:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.1.1/lib/active_suppo rt/dependencies.rb:183:inconst_missing’
from (irb):1

However if i remove this validation and use validate things are fine.

I dont know why? Any pointers? Why does validates_exclusion_of not able
to convert the symbol :receivers into deal.receivers :-(?


#2

Hi !

2005/11/18, Deepak S. removed_email_address@domain.invalid:

I dont know why? Any pointers? Why does validates_exclusion_of not able
to convert the symbol :receivers into deal.receivers :-(?

validates_inclusion_of and validates_exclusion_of only work with
static arrays (or enumerables). You’ll need to write the validation
rule yourself:

validates_each :payer do | record, attr, value|
record.errors.add(attr, ‘is part of the receivers list’) if
record.receivers.include?(value)
end

Hope that helps !


#3

francois.beausoleil wrote:
Hi Franc,

A ticket has been opened…http://dev.rubyonrails.org/ticket/2935

Also your solution works. Thanks.

I had tested with a fix on validations.rb. Just like validates_each uses
an attr,value combo validates_exclusion_of doesnt convert the enum into
a record.send(attr). Hence we cant use symbols. Howver in 1.1 we can :slight_smile:

Cheers
Deepak S.