Rails - validates_associated 两个 has_many 关系
Rails - validates_associated on two has_many relationship
我想 validate/prevent 一个不存在的 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
我select一个Professor
,修改Professor.id
并保存。 Rails 显示以下错误:
ActiveRecord::RecordNotFound (Couldn't find Professor with id=123 [WHERE "pessoas"."tipo" = 1])
有什么方法可以在 ActiveModel 的验证方法上验证这个假 ID?
您应该向 turma.rb 添加验证。
先决条件:
我猜你的控制器是这样的。
# 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)
所以你应该在你的 Turma
模型中捕捉 ActiveRecordd::RecordNotFound
。
如何添加验证:
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"]
正好有一个 gem:https://github.com/perfectline/validates_existence
在您的连接模型上使用 validates: :turma, existence: true
,一切都应该按预期工作。
您可能还想在关联的某处添加 dependent: destroy
(否则您可能会得到指向已删除项目的无效关联),并且可能使用新添加的 add_foreign_key
迁移语句以保证数据库级别的链接完整性。
我想 validate/prevent 一个不存在的 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
我select一个Professor
,修改Professor.id
并保存。 Rails 显示以下错误:
ActiveRecord::RecordNotFound (Couldn't find Professor with id=123 [WHERE "pessoas"."tipo" = 1])
有什么方法可以在 ActiveModel 的验证方法上验证这个假 ID?
您应该向 turma.rb 添加验证。
先决条件:
我猜你的控制器是这样的。
# 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)
所以你应该在你的 Turma
模型中捕捉 ActiveRecordd::RecordNotFound
。
如何添加验证:
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"]
正好有一个 gem:https://github.com/perfectline/validates_existence
在您的连接模型上使用 validates: :turma, existence: true
,一切都应该按预期工作。
您可能还想在关联的某处添加 dependent: destroy
(否则您可能会得到指向已删除项目的无效关联),并且可能使用新添加的 add_foreign_key
迁移语句以保证数据库级别的链接完整性。