开发者

How can I write a validation that will ensure an existing association cannot be changed in Rails 3?

I have seen many questions asking how to validate the presence of an association, but this question is a bit more complex.

Say I have three models, a Plane, a Pilot, and a Flight.

A Plane can have one Pilot and one Flight.

Once a Plane has been assigned a Pilot, it can then be assigned a Flight.

I would like to write some validation code to ensure that once a Plane has both a Flight and a Pilot, the Pilot cannot be changed. So I would like this test to pass:

开发者_开发知识库
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

I would love some insight as to what techniques are available to accomplish this. Thanks all!


You could start with a custom validation that checks the changed record (sitting in memory) against the underlying record that's actually in the database.

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


you can write your own validation to ensure this.. but that wouldn't return false to you in the moment you assign a pilot, but at the end, when you save the plane.

So here is simpler version:

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

Hope this helps (or at least navigate you the right direction).

Regards, NoICE

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜