I would like to know if there's a way to when doing STI the
update_attributes, validate the attributes based on the new class type?
For e.g. suppose i have:
class A < ActiveRecord::Base
end
class B < A
validates :attribute_z, :presence => true
end
class C < A
validates :attribute_x, :presence => true
validates :attribute_y, :presence => true
end
If i run (the way rails is implemented):
b = A.find('b-id')
b.update_attributes({ 'type' => 'C', :attribute_x => 'present',
:attribute_y => 'present', :attribute_z => nil }) # will return false
with
errors on 'attribute_z must be present'
I've tried with
#becomes[http://api.rubyonrails.org/classes/ActiveRecord/Pe...
b = A.find('b-id')
b = b.becomes(C)
b.update_attributes({ 'type' => 'C', :attribute_x => 'present',
:attribute_y => 'present', :attribute_z => nil })
# this works partially, because the validations are ok but when i
look
to console i get something like:
UPDATE "as" SET "type" = 'c', "attribute_z" = NULL, "attribute_y' =
'present', 'attribute_x' = 'present' WHERE "as"."type" IN ('C') AND
"as"."id" = 'b-id'
# which is terrible because it's looking for a record of B type on
the
C types.
i could put :if => proc { |record| record.type == 'C' } on the
validations
and put the validations at A class. But it wouldn't make sense to have
the
subclasses. The difference basically of B and C is only in the
validation
behavior. (I have many validations on both types)
on 2013-01-15 11:25
on 2013-01-16 19:56
Why are you doing
b = A.find("b-id") and not b = B.find("b-id") ?
I think it would be better if you did
b = B.find("b-id")
c = b.becomes(C)
try it in the console and verify that c.class is C
then you should be able to do
c.update_attributes(:attribute_x => 'present', :attribute_y =>
'present')
Your validations will fail if you expect Rails to make the update to an
object of class B without attribute_z, which is what you're doing here:
b.update_attributes({ 'type' => 'C', :attribute_x => 'present',
:attribute_y => 'present', :attribute_z => nil })
You need b to be of class C if you want your validations to pass.
on 2013-01-17 16:58
On Monday, 14 January 2013 13:34:29 UTC-5, Guilherme Reis wrote: > i could put :if => proc { |record| record.type == 'C' } on the validations > and put the validations at A class. But it wouldn't make sense to have the > subclasses. The difference basically of B and C is only in the validation > behavior. (I have many validations on both types) > Are you positive A, B and C should really be separate classes? The fact that there are transitions that change classes makes it sound a lot like there's really a statemachine here, not a class hierarchy... --Matt Jones
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.