gpt4 book ai didi

ruby-on-rails - 在分配虚拟属性时发出信号验证错误?

转载 作者:行者123 更新时间:2023-12-02 00:46:34 26 4
gpt4 key购买 nike

这是一个 Rails/ActiveRecord 问题。

我有一个模型,基本上必须代表事件 或表演。每个事件都有许多归因:归因基本上类似于“在此事件中,X 人担任 Y 角色”。

我得出的结论是,允许用户编辑此数据的最佳方法是提供一个需要结构化格式的自由文本字段,我将其称为角色字符串:

歌手:Elvis Costello,词曲作者:Paul McCartney,...

我使用自动完成来完成角色名称(歌手、词曲作者...)和人名。角色和人员都存储在数据库中。

为了实现这一点,我在事件模型中创建了一个虚拟属性:

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 没有引用有效的人,会发生什么情况?

我想,好吧,我可以在属性 :role_string 上使用 validates_each 来查找关联,如果给定的名称之一不匹配则抛出错误任何东西,例如。

我的问题有两个:首先,我不喜欢这种方法,因为要验证关联,我必须解析字符串并查找它们,这重复了我在 role_string= 本身,除了实际将关联保存到数据库。

其次,...我如何指示在分配给该虚拟属性时发生错误?

最佳答案

首先,您错误地将人物归因于事件。您应该将一个人的 ID 传递给事件,而不是传递一个人名的字符串。例如,如果 ID 为 230404 且名称为“Elvis Costello”的 Person 将其名称更改为“Britney Spears”怎么办?好吧,如果发生这种情况,ID 将保持不变,但名称会改变。但是,您将无法再引用该人。

您应该设置您的关联,以便外键在多种情况下引用人:

has_one :singer, :class_name => "Person", :foreign_key => "singer_id"
has_one :songwriter, :class_name => "Person", :foreign_key => "songwriter_id"

这样,您可以让多个人在不同的角色下与一个事件相关联,并且您可以引用 Person 可能具有的多个属性。例如:

Event.first.singer.name   # => "Elvis Costello"
Event.first.songwriter.name # => "Britney Spears"

您可以研究关联的可用验证 (validates_associated),以及 ID 是否存在于表单中 (validates_presence_of)。我建议创建您自己的自定义验证以确保一个人在 before_save 之前有效。像(未经测试):

def before_save
unless Person.exists?(self.songwriter_id)
self.errors.add_to_base("Invalid songwriter. Please try again!")
return false
end
end

此外,我注意到您正在寻找一种方法让用户选择一个用户,该用户应该用于您的事件中的角色。以下是您可以在部分表单中执行的操作:

select(:event, :singer_id, Person.find(:all).collect {|p| [ p.name, p.id ] }, { :include_blank => 'None' })

希望这对您有所帮助!

关于ruby-on-rails - 在分配虚拟属性时发出信号验证错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/323610/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com