ruby-on-rails - 验证 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!
由于编写器和笔记本之间没有关联,因此会引发验证错误。
解决方案
首先从创建间接关联开始:
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 处理的授权问题,而不是验证应该处理的错误用户输入问题。
推荐阅读
- javascript - 如何使一个类的实例同时具有可比性和可垃圾收集?
- azure - 将现有 b2c 租户链接到我的 Azure 订阅但无法创建资源?
- c# - 引入自定义验证器时无法访问 WCF 服务元数据
- express - UI5 路由实现:Express.js 与 UI5 路由功能
- ffmpeg - 编辑 m4s 文件视频
- android - 谷歌登录后如何转换到另一个屏幕?
- tcp - Bytes to receive on gen_tcp:recv by parsing json
- hyperledger-fabric - 关于使用 Fabric-CA 节点 sdk 进行用户注册的问题
- c - 用于生成 ftok() 密钥的公式是什么?
- c# - 将项目添加到 ObservableCollection 时出现 InteropServices.COMException