Michael Greenly
2006-May-26 20:31 UTC
[Rails] Using ''validates_inclusion_of'' to validate foreign key
I seem to be missing something trying to use ''validates_inclusion_of'' to validate a foreign key and was hoping some one could piont out my mistake? The problem seems to be that Order.find_all.collect is not returning an array that contains the order_id, if I replace it with a hardcoded array everything works as expected. The model: class OrderItem < ActiveRecord::Base validates_inclusion_of :order_id, :in => Order.find_all.collect { |order| order.id } belongs_to :order end The test: class OrderItemTest < Test::Unit::TestCase fixtures :orders, :order_items def test_validates_inclusion_of_order_id_in_orders orderitem = OrderItem.new(:order_id => 1) assert( orderitem.save, orderitem.errors.full_messages.join(''\n'')) end end The fixture: first: id: 1 sid: ''ON001'' All of the code can be found at http://metaspot.net/dev/browser/?rev=46 -- Posted via http://www.ruby-forum.com/.
Michael Greenly
2006-May-26 21:44 UTC
[Rails] Re: Using ''validates_inclusion_of'' to validate foreign key
Michael Greenly wrote:> The problem seems to be that Order.find_all.collect is not returning an > array that contains the order_id, if I replace it with a hardcoded array > everything works as expected. >Guess I''ll respond to my own post... This was most likley a bad idea anyway. I really don''t want to suck an entire table index into an array every time I want to create or update a new row. I should of just created a validation that did something like this.... def validate begin Order.find(self.order_id) rescue ActiveRecord::RecordNotFound errors.add(:order_id, "invalid foreign key reference") end end -- Posted via http://www.ruby-forum.com/.
Jonathan Viney
2006-May-26 21:46 UTC
[Rails] Using ''validates_inclusion_of'' to validate foreign key
You might have difficulty using :in => to achieve that. A custom validation is probably in order. For performance reasons, it''s probably worth adding a method to ActiveRecord::Base to select just the model ids. That will save you from having to instantiate all the model objects each time the validation occurs. class ActiveRecord::Base def self.ids connection.select_values("select #{primary_key} from #{table_name}").collect(&:to_i) end end class OrderItem belongs_to :order def validate errors.add_to_base "Invalid order" unless Order.ids.include?(order_id) end end -Jonathan On 5/27/06, Michael Greenly <mgreenly@gmail.com> wrote:> I seem to be missing something trying to use ''validates_inclusion_of'' to > validate a foreign key and was hoping some one could piont out my > mistake? > > The problem seems to be that Order.find_all.collect is not returning an > array that contains the order_id, if I replace it with a hardcoded array > everything works as expected. > > The model: > > class OrderItem < ActiveRecord::Base > validates_inclusion_of :order_id, :in => Order.find_all.collect { > |order| order.id } > belongs_to :order > end > > The test: > > class OrderItemTest < Test::Unit::TestCase > fixtures :orders, :order_items > def test_validates_inclusion_of_order_id_in_orders > orderitem = OrderItem.new(:order_id => 1) > assert( orderitem.save, orderitem.errors.full_messages.join(''\n'')) > end > end > > The fixture: > first: > id: 1 > sid: ''ON001'' > > All of the code can be found at http://metaspot.net/dev/browser/?rev=46 > > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
Jonathan Viney
2006-May-27 00:01 UTC
[Rails] Re: Using ''validates_inclusion_of'' to validate foreign key
That is probably a better approach. Using Order.exists? will make the code a bit shorter: errors.add_to_base ''Invalid order'' unless Order.exists?(order_id) -Jonathan.> > def validate > begin > Order.find(self.order_id) > rescue ActiveRecord::RecordNotFound > errors.add(:order_id, "invalid foreign key reference") > end > end >
Michael Greenly
2006-May-27 02:06 UTC
[Rails] Re: Re: Using ''validates_inclusion_of'' to validate foreign k
Jonathan Viney wrote:> That is probably a better approach. Using Order.exists? will make the > code a bit shorter: > > errors.add_to_base ''Invalid order'' unless Order.exists?(order_id) > > -Jonathan.Much better, it''s starting to look a bit more like ruby... now that it''s been expressed in a single line ;) Thanks -- Posted via http://www.ruby-forum.com/.