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/.