How to override append method for related attribute?

I have a model that looks something like this:

class Person < ActiveRecord::Base
has_many :tasks
[…]
end

I’d like to override/overload the append (<<) method for the tasks
relational attribute such that I can perform some error checking in
the context of a Person.tasks << task operation. Is there any way to
do this?

I wish I could do this in the context of validation, but it appears
that appending a task instance to a list associated with a person
instance causes the model to be saved in the database even if doing
the operation would cause validation to fail. i.e., person.valid?
will return false as one would expect, but the data will persist!

I’d love your input on this matter.

–Michael

Michael S. Fischer wrote:

do this?

I wish I could do this in the context of validation, but it appears
that appending a task instance to a list associated with a person
instance causes the model to be saved in the database even if doing
the operation would cause validation to fail. i.e., person.valid?
will return false as one would expect, but the data will persist!

Invalid records will persist in the loaded collection array, but
will not be saved to the database. Are you sure the invalid
object is getting saved to the DB?


We develop, watch us RoR, in numbers too big to ignore.

Michael S. Fischer wrote:

I have a model that looks something like this:

class Person < ActiveRecord::Base
has_many :tasks
[…]
end

I’d like to override/overload the append (<<) method for the tasks
relational attribute such that I can perform some error checking in
the context of a Person.tasks << task operation. Is there any way to
do this?

You can do that with an association extension:

has_many :tasks do
def <<(task)
if task.should_be_appended
concat(task) # aliased to << in base association proxy
else
raise SomeException
end
end
end

I wish I could do this in the context of validation, but it appears
that appending a task instance to a list associated with a person
instance causes the model to be saved in the database even if doing
the operation would cause validation to fail. i.e., person.valid?
will return false as one would expect, but the data will persist!

If the appended object fails validation then the << won’t succeed. Can
you put the validation test in Task instead of in Person?


Josh S.
http://blog.hasmanythrough.com

On 8/5/06, Josh S. [email protected] wrote:

    concat(task)  # aliased to << in base association proxy
  else
    raise SomeException
  end
end

end

Sexy, thanks!

I wish I could do this in the context of validation, but it appears
that appending a task instance to a list associated with a person
instance causes the model to be saved in the database even if doing
the operation would cause validation to fail. i.e., person.valid?
will return false as one would expect, but the data will persist!

If the appended object fails validation then the << won’t succeed. Can
you put the validation test in Task instead of in Person?

Indeed, moving the test to Task did the trick. Thanks!

–Michael