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 [email protected].
To unsubscribe from this group, send email to 
[email protected].
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.


Reply via email to