【发布时间】:2011-07-29 15:11:52
【问题描述】:
在O'Reilly 的“Head first Rails”(2009 年编)的这个练习中,有 2 个相关对象。
"Flight" 对象[我使用 annotate gem 来显示每个属性]:
# == Schema Information
#
# Table name: flights
#
# id :integer not null, primary key
# departure :datetime
# arrival :datetime
# destination :string(255)
# baggage_allowance :decimal(, )
# capacity :integer
# created_at :datetime
# updated_at :datetime
#
class Flight < ActiveRecord::Base
has_many :seats
end
蚂蚁“座位”对象:
# == Schema Information
#
# Table name: seats
#
# id :integer not null, primary key
# flight_id :integer
# name :string(255)
# baggage :decimal(, )
# created_at :datetime
# updated_at :datetime
#
class Seat < ActiveRecord::Base
belongs_to :flight
end
正如您可能猜到的那样,seat.baggage 值应始终小于或等于 seat.flight.baggage_allowance。
所以我写了这个验证器,效果很好:
class Seat < ActiveRecord::Base
belongs_to :flight
def validate
if baggage > flight.baggage_allowance
errors.add_to_base("Your have to much baggage for this flight!")
end
end
end
然后我尝试用这个更漂亮的重构它:
validates :baggage, :numericality => { :less_than_or_equal_to => flight.baggage_allowance }, :presence => true
但它会在 SeatsController 中导致 NameError:
undefined local variable or method `flight' for #<Class:0x68ac3d8>"
比我还尝试使用“self.flight.baggage_allowance”:
validates :baggage, :numericality => { :less_than_or_equal_to => self.flight.baggage_allowance }, :presence => true
但它会抛出 NoMethodError 异常:
undefined method `flight' for #<Class:0x67e9b40>
有没有办法让更漂亮的验证器工作?
进行此类验证的最佳做法是什么?
谢谢。
---编辑---
正如 Maurício Linhares 之后所建议的那样,定义一个 :bagging_allowance 符号是可以解决问题的。 我想更好地了解真正需要自定义验证的地方。 那么这个呢,是否可以将 this 转换为“验证”方法?为什么?
class Seat < ActiveRecord::Base
.
.
.
def validate
if flight.capacity <= flight.seats.size
errors.add_to_base("The flight is fully booked, no more seats available!")
end
end
再次感谢您。
【问题讨论】:
-
在验证器中尝试匿名函数:
:less_than_or_equal_to => Proc.new { |flight| flight.baggage_allowance } -
我写了:
validates :baggage, :numericality => { :less_than_or_equal_to => Proc.new { |flight| flight.baggage_allowance }}, :presence => true它抛出:NoMethodError in SeatsController#create undefined method 'baggage_allowance' for #<Seat:0x6a8be38>无论如何谢谢!
标签: ruby-on-rails ruby-on-rails-3 validation customvalidator