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/Persistence.html#method-i-becomes]:
    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)
-- 
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
To view this discussion on the web visit
https://groups.google.com/d/msg/rubyonrails-talk/-/kD4U2PKWfhMJ.
For more options, visit https://groups.google.com/groups/opt_out.
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 Monday, January 14, 2013 1:34:29 PM UTC-5, Guilherme Reis
wrote:>
> 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/Persistence.html#method-i-becomes
> ]:
>
>     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)
>
>
-- 
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
To view this discussion on the web visit
https://groups.google.com/d/msg/rubyonrails-talk/-/_c5hEbbc09EJ.
For more options, visit https://groups.google.com/groups/opt_out.
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 -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-talk/-/b1z0OH96yBoJ. For more options, visit https://groups.google.com/groups/opt_out.