Dar*_*rme 5 validation ruby-on-rails customvalidator ruby-on-rails-3
在O'Reilly的"Head first Rails"(编辑,2009)的练习中,有2个相关的对象.
在"飞行"的对象[我用来注释宝石显示每个属性]:
# == 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
Run Code Online (Sandbox Code Playgroud)
Ant "Seat"对象:
# == 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
Run Code Online (Sandbox Code Playgroud)
您可能猜测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
Run Code Online (Sandbox Code Playgroud)
然后我试着用这个更漂亮的那个重构它:
validates :baggage, :numericality => { :less_than_or_equal_to => flight.baggage_allowance }, :presence => true
Run Code Online (Sandbox Code Playgroud)
但它导致SeatsController中的NameError:
undefined local variable or method `flight' for #<Class:0x68ac3d8>"
Run Code Online (Sandbox Code Playgroud)
比我还试过"self.flight.baggage_allowance":
validates :baggage, :numericality => { :less_than_or_equal_to => self.flight.baggage_allowance }, :presence => true
Run Code Online (Sandbox Code Playgroud)
但它会引发NoMethodError异常:
undefined method `flight' for #<Class:0x67e9b40>
Run Code Online (Sandbox Code Playgroud)
有没有办法让更漂亮的验证器工作?
进行此类验证的最佳做法是哪种?
谢谢.
- -编辑 - -
正如毛里西奥·林哈里斯(MaurícioLinhares)此后提出的那样,问题是可以解决的:定义:bagging_allowance符号.我想更好地了解真正需要自定义验证的地方.这个怎么样,是否有可能将此转换为"验证"方法?为什么?
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
Run Code Online (Sandbox Code Playgroud)
再次感谢你.
你可以这样做:
class Seat < ActiveRecord::Base
validates :baggage, :numericality => { :less_than_or_equal_to => :baggage_allowance }, :presence => true
belongs_to :flight
def baggage_allowance
flight.baggage_allowance
end
end
Run Code Online (Sandbox Code Playgroud)
编辑
你不能这样做:
class Seat < ActiveRecord::Base
validates :baggage, :numericality => { :less_than_or_equal_to => flight.baggage_allowance }, :presence => true
end
Run Code Online (Sandbox Code Playgroud)
因为方法验证是在类级别调用的,所以没有可用的飞行变量,因为它是一个实例变量.当您使用:baggage_allowance对其进行配置时,您可以告诉Rails在Seat实例上调用:baggage_allowance方法以便能够访问该值.
归档时间: |
|
查看次数: |
2472 次 |
最近记录: |