Как я могу написать валидацию, которая обеспечит невозможность изменения существующей ассоциации в Rails 3? - PullRequest
1 голос
/ 21 мая 2011

Я видел много вопросов, спрашивающих, как проверить наличие ассоциации, но этот вопрос немного сложнее.

Скажем, у меня есть три модели: Plane, Pilot и Flight.

A Plane может иметь один Pilot и один Flight.

Как только Plane был присвоен Pilot, ему можно присвоить Flight.

Я хотел бы написать некоторый проверочный код, чтобы гарантировать, что если Plane имеет и Flight, и Pilot, Pilot не может быть изменено. Так что я хотел бы этого пройти тест:

describe Plane do
    context "before updating" do
        it "ensures that the pilot cannot be changed if the plane has any flights" do
            plane        = Plane.create!
            plane.pilot  = Pilot.create!
            plane.flight = Flight.create!

            hijacker = Pilot.create!
            plane.pilot = hijacker

            plane.save.should be_false
            plane.errors[:base].should include "Can't change the pilot while in-flight"
        end
    end
end

Мне бы хотелось немного понять, какие методы доступны для достижения этой цели. Спасибо всем!

Ответы [ 2 ]

2 голосов
/ 21 мая 2011

Вы можете начать с пользовательской проверки, которая проверяет измененную запись (находящуюся в памяти) на соответствие базовой записи, которая фактически находится в базе данных.

class Plane < ActiveRecord::Base
  validate_on_update :pilot_cannot_be_changed

  def pilot_cannot_be_changed
    errors.add(:pilot, "cannot be changed while in-flight.") 
      if pilot.id != Plane.find(id).pilot.id
  end
0 голосов
/ 21 мая 2011

Вы можете написать свою собственную проверку, чтобы гарантировать это .. но это не вернет вам ложь в тот момент, когда вы назначите пилота, но в конце, когда вы сохраните самолет.

Итак, вот более простая версия:

class Plane < ActiveRecord::Base

  def pilot=(val)
    return false if self.pilot && self.flight
    @pilot = val
    # I'm not sure about this line above, you can use something like this (or both lines)
    # write_attribute(:pilot_id, val.id)
  end

end

Надеюсь, это поможет (или, по крайней мере, поможет вам выбрать правильное направление).

С уважением, NoICE

...