В этом упражнении из О'Рейли "Head first Rails" (ed. 2009) есть 2 связанных объекта .
Объект "Flight" [Я использовал гем-аннотацию, чтобы показать все атрибуты]:
# == 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
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
Как вы можете догадаться, значение 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
Но это вызывает NameError в SeatsController:
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>
Есть способ сделать валидатор красивее работает?
Как лучше всего проводить такую проверку?
Спасибо.
--- РЕДАКТИРОВАТЬ ---
Как любезно предложил Маурисио Линьярес в дальнейшем, проблему можно решить, определив: 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
Еще раз спасибо.