Как проверить атрибут с помощью «validates: attribute», относящегося к значению атрибута родительского объекта?

В этом упражнении из О'Рейли "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

Еще раз спасибо.

5
задан Darme 12 March 2015 в 17:01
поделиться