如何编写验证以确保在Rails 3中无法更改现有关联?

时间:2011-05-21 05:30:41

标签: ruby-on-rails ruby-on-rails-3 validation associations

我已经看到很多问题,询问如何验证关联的存在,但这个问题有点复杂。

假设我有三个模型,PlanePilotFlight

Plane可以有一个Pilot和一个Flight

Plane分配Pilot后,可以为其分配Flight

我想写一些验证码,以确保Plane同时拥有FlightPilotPilot无法更改。 所以我希望这个测试通过:

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 个答案:

答案 0 :(得分:2)

您可以从自定义验证开始,该验证检查已更改的记录(位于内存中)与实际位于数据库中的基础记录。

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

答案 1 :(得分:0)

你可以编写自己的验证来确保这一点.. 但是在你指派飞行员的那一刻,这不会给你带来错误,但最后,当你保存飞机时。

所以这里的版本更简单:

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