首页 > 解决方案 > 验证 ActiveRecord 模型具有相同的关联/组

问题描述

因此,我正在尝试对两个 ActiveRecord 模型进行自定义验证。我正在处理的应用程序包含 3 个模型;一个笔记,一个作家和一个笔记本。每当我通过表单创建笔记时,我想验证它是否具有与作者当前在创建或更新时允许使用的完全相同的笔记本。

模型看起来真的很简化,就像这样;

class Notebook < ApplicationRecord
   has_many :notes
   has_many :writers
end

class Writer < ApplicationRecord
   has_many :notes
   belongs_to: notebook
end

class Note < ApplicationRecord
   belongs_to: writer
   belongs_to: notebook
end

所以每当我做这样的事情时;

another_notebook = Notebook.new

writer = Writer.new

note = Note.new(writer: writer, notebook: another_notebook)
note.save!

由于编写器和笔记本之间没有关联,因此会引发验证错误。

标签: ruby-on-railsrubyactiverecordrails-activerecord

解决方案


首先从创建间接关联开始:

class Notebook < ApplicationRecord
   has_many :notes
   has_many :writers, through: :notes
end

class Note < ApplicationRecord
   belongs_to: writer
   belongs_to: notebook
end

class Writer < ApplicationRecord
   has_many :notes
   has_many :notebooks, through: :notes
   # ...
end

这会在 Notebook 和 Writer 之间创建多对多关联。

如果您想添加writer只能在特定笔记本中创建笔记的规则:

class Writer < ApplicationRecord
   has_many :notes
   has_many :notebooks, through: :notes
   belongs_to :current_notebook, class: 'Notebook'
end

class Note < ApplicationRecord
  # ...
  validate :is_current_notebook

  def is_current_notebook
    unless notebook == writer.current_notebook
      errors.add(:notebook, 'is not valid.')
    end
  end
end

但是,我会考虑这是否真的适合模型验证,因为它似乎更像是应该由 CanCanCan 或 Pundit 处理的授权问题,而不是验证应该处理的错误用户输入问题。


推荐阅读