我想在尝试保存模型之前验证/阻止不存在的FK。
class Turma < ActiveRecord::Base
has_many :turma_professor
has_many :professores, through: :turma_professor
accepts_nested_attributes_for :professores
end
class TurmaProfessor < ActiveRecord::Base
belongs_to :turma
belongs_to :professor
end
class Professor < ActiveRecord::Base
has_many :turma_professor
has_many :turma, :through => :turma_professor
end
我选择Professor
,更改Professor.id
并保存。 Rails向我显示以下错误:
ActiveRecord::RecordNotFound (Couldn't find Professor with id=123 [WHERE "pessoas"."tipo" = 1])
有一些方法可以在ActiveModel的验证方法上验证这个假身份证吗?
答案 0 :(得分:1)
您应该将验证添加到 turma.rb 。
<强> PREFEQUISITE:强>
我想你的控制器就像下面一样。
# Not raise exception because professore_ids 1, 3 exist.
Turma.new(professore_ids: [1, 3])
Professor Load (0.9ms) SELECT "professors".* FROM "professors" WHERE "professors"."id" IN (1, 3)
=> #<Turma id: nil, name: nil, created_at: nil, updated_at: nil>
# Raise exception because professore_id 4 doesn't exist.
Turma.new(professore_ids: [1, 4])
Professor Load (0.9ms) SELECT "professors".* FROM "professors" WHERE "professors"."id" IN (1, 4)
ActiveRecord::RecordNotFound: Couldn't find all Professors with 'id': (1, 4) (found 1 results, but was looking for 2)
因此,您应该在ActiveRecordd::RecordNotFound
模型中抓住Turma
。
如何添加验证:
class Turma < ActiveRecord::Base
# declear not_found_professor_ids flag
attr_reader :not_found_professor_ids
has_many :turma_professor
has_many :professores, through: :turma_professor, source: :professor
accepts_nested_attributes_for :professores
# validation
validates :not_found_professor_ids, inclusion: { in: [true], message: "don't found" }
def professore_ids=(ids)
super(ids)
rescue ActiveRecord::RecordNotFound
# set flag
self.not_found_professor_ids = true
end
end
并使用它。
turma = Turma.new(professore_ids: [1,4])
turma.valid? #=> false
turma.errors.full_messages #=> ["Not found professor ids don't found"]
答案 1 :(得分:0)
确切地说有一个宝石:https://github.com/perfectline/validates_existence
在您的联接模型上使用validates: :turma, existence: true
,一切都应该按预期工作。
您可能还想将dependent: destroy
添加到您的关联中(或者您最终会指向指向已删除项目的无效关联),并且可能使用新添加的add_foreign_key
迁移语句来保证数据库级别的链接完整性。