这是一个 Rails/ActiveRecord 问题。
我有一个模型,它基本上必须代表事件或表演。每个事件都有许多属性:属性基本上类似于“在这个事件中,人 X 有角色 Y”。
我得出的结论是,允许用户编辑此数据的最佳方法是提供一个需要结构化格式的自由文本字段,我将其称为角色字符串:
singer: Elvis Costello, songwriter: Paul McCartney, ...
我使用自动完成功能来完成角色名称(歌手、词曲作者......)和人名。角色和人员都存储在数据库中。
为了实现这一点,我在 Event 模型中创建了一个虚拟属性:
def role_string
# assemble a role string from the associations in the model
end
def role_string=(s)
# parse a string in the above role string format,
# look up the People and Events mentioned, and update
# what's in the database
end
这一切都很好。当角色字符串格式正确并且角色字符串给出的关联都检查出来时,整个事情运行得很好。
但是如果角色字符串格式不正确怎么办?好的,我想,我可以使用正则表达式和标准验证来检查格式:
validates_format_of :role_string, :with => /(\w+:\s*\w+)(,\s*\w+:\s*\w+)*/
但是如果角色字符串隐含的关联无效怎么办?例如,如果我给上面的角色字符串,并且Elvis Costello
没有引用一个有效的人,会发生什么?
我想,好吧,我可以使用validates_each
属性:role_string
来查找关联,如果给定的名称之一不匹配任何内容,则抛出错误。
我的问题有两个:首先,我不喜欢这种方法,因为要验证关联,我必须解析字符串并查找它们,这重复了我自己要做的事情role_string=
,除了实际将关联保存到数据库。
其次,......我如何表明在分配给这个虚拟属性时发生了错误?