自定义字段转换是否受最近更新影响?

过去两天内,关于events 插件的多个错误报告都似乎与自定义字段的类型转换问题有关。该 events 插件已有数月未进行实质性更新。

plugin.rb 文件将 event_start 强制转换为整数:

Topic.register_custom_field_type('event_start', :integer)

错误在此处抛出:

def has_event?
  self.custom_fields['event_start']&.nonzero?
end

错误信息格式如下:

NoMethodError (undefined method `nonzero?' for [1563127206, 1563127206]:Array)

据我所知,register_custom_field_type 应确保自定义字段始终返回定义的类型(或许我理解有误)。

查看 has_custom_fields.rb 模块,过去一周内有一些变更可能影响了此问题,特别是:

@eviltrout 对此有何看法?

如果这确实是导致问题的漏洞,以下是其后果(可能导致您的网站无法使用):

这确实是一个与自定义字段相关的已知 bug。

在非常特定的条件下,系统会将该值多次保存,从而生成一个数组,而您实际上只需要一个整数。

您可以通过确保数据库中每个自定义字段只有一行记录来修复此问题。

是的,过去确实出现过几次。最近这一波问题似乎与 has_custom_fields.rb 关注点的近期工作相吻合,因此那里可能需要审查。

这并不能彻底修复该问题,但有助于在问题出现时进行处理:

我的一般建议是,作为插件作者,您应在迁移中始终添加索引,以正确强制执行约束。事实上,我们目前开发的多数插件都会尽量避免使用自定义字段(除非绝对必要),而更倾向于使用自定义表,因为自定义表更容易理解和管理。针对此特定情况,您需要创建如下索引:

create unique index idxStartEvent on topic_custom_fields(topic_id) where name = 'start_event'

我不确定核心部分还需要做什么。我们曾考虑过对自定义字段进行全面重构,但对此有些顾虑。目前我正在考虑的一个方案是直接移除自定义字段对数组的支持,因为多年来它们引发了大量问题。

抱歉再次顶起这个帖子,但其中一个条件是当您使用符号索引(例如 custom_fields[:hello])更新现有值时,它会添加另一个字段而不是更新,从而导致出现数组。我认为这可能是唯一的条件。

这几乎肯定能修复由此产生的副作用。