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

There have been multiple bug reports for the events plugin in the last two days that all seem to be type-casting issues with custom fields. The events plugin hasn’t been substantively updated in a few months.

The plugin.rb file casts event_start as an integer:

Topic.register_custom_field_type('event_start', :integer)

The error is being thrown here:

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

The error itself follows this format:

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

As far as I understand register_custom_field_type it should ensure that the custom_field always returns as the defined type (perhaps I’m misunderstanding it).

Looking at the has_custom_fields.rb concern, there have been a few changes in the past week that could have affected this, in particular

@eviltrout Any thoughts on this?

In case this is indeed the bug causing problems, here I explain the consequences (it may make your site unusable):

This was a known bug with custom fields.

In very specific conditions, it would save the value multiple times, thus creating an Array, when you only want an Integer.

You can fix this by making sure there’s only 1 row per custom field in the database.

Yes, it’s cropped up a few times in the past. This latest rash seems to coincide with recent work on the has_custom_fields.rb concern, so there may be something to review there.

This doesn’t fix it, but helps to address it if it arises:

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

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

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

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

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