I have the following models: class Address < ActiveRecord::Base validates_format_of :zip, :with => /\A[0-9]{5}\z/, :allow_blank => false validates_presence_of :address1 validates_presence_of :state belongs_to :user end # the inherited records are in a subdirectory class Addresses::ShipFromAddress < Address belongs_to :transaction end class Addresses::ShipToAddress < Address belongs_to :transaction end class Transaction < ActiveRecord::Base has_one :ship_to_address, :class_name => "Address", :dependent => :destroy has_one :ship_from_address, :class_name => "Address", :dependent => :destroy end I can access transaction.ship_to_address and transaction.ship_from_address but the query that''s generated for both is: SELECT `addresses`.* FROM `addresses` WHERE `addresses`.`transaction_id` = 5 LIMIT 1 There''s no expected type constraint. However, if I do: Addresses::ShipToAddress.find_by_transaction_id(5) the query is correct as: SELECT `addresses`.* FROM `addresses` WHERE `addresses`.`type` IN (''Addresses::ShipToAddress'') AND `addresses`.`transaction_id` = 5 LIMIT 1 I have the workaround but it bugs me that the transaction.ship_to_address doesn''t work correctly. The one thing that may be wonky is that I''m putting "non-typed" ActiveRecord superclass entries into addresses but that shouldn''t be an issue? -- Posted via http://www.ruby-forum.com/. -- 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 For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Frederick Cheung
2011-Oct-17 15:28 UTC
Re: ActiveRecord STI not restricting type in queries
On Oct 17, 3:20 pm, "Dave G." <li...-fsXkhYbjdPsEEoCn2XhGlw@public.gmane.org> wrote:> I can access transaction.ship_to_address and > transaction.ship_from_address but the query that''s generated for both > is: > SELECT `addresses`.* FROM `addresses` WHERE `addresses`.`transaction_id` > = 5 LIMIT 1 > > There''s no expected type constraint. > > However, if I do: > Addresses::ShipToAddress.find_by_transaction_id(5) the query is correct > as: > SELECT `addresses`.* FROM `addresses` WHERE `addresses`.`type` IN > (''Addresses::ShipToAddress'') AND `addresses`.`transaction_id` = 5 LIMIT > 1 > > I have the workaround but it bugs me that the > transaction.ship_to_address doesn''t work correctly. The one thing that > may be wonky is that I''m putting "non-typed" ActiveRecord superclass > entries into addresses but that shouldn''t be an issue?You''ve told active record that ship_to_address is just a regular address (since you''ve got class_name => ''Address''), so active record believes you. If ship_to_address should only ever by a Addresses::ShipToAddress then you need to let active record know. Fred> > -- > Posted viahttp://www.ruby-forum.com/.-- 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@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
That doesn''t work. I was under the impression that if the ActiveRecord class name wasn''t obvious that it needed to be specified. In fact, if I take that out, I get errors about Addresses::ShipToAddress not being a defined constant when trying transaction.ship_to_address. Maybe I need so specify the :class to be Adddresses::ShipToAddress? But that doesn''t make a whole lot of sense to me because that, specifically, is derivable from "has_one :ship_to_address" and I don''t understand what the syntax would be anyway. -- Posted via http://www.ruby-forum.com/. -- 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 For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Ok, that DOES work. I don''t know what I was doing but I thought I tried that *several* times. My coworker looked at it and had me try it again and voila, the line is: has_one :ship_to_address, :class_name => ''Addresses::ShipToAddress'', :dependent => :destroy Thank you! -- Posted via http://www.ruby-forum.com/. -- 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 For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.