Custom field casting affected by recent update?

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

https://github.com/discourse/discourse/commit/72bac61c90044407f7a2029b15f6ac043a8bccf0#diff-712e064741bd664591e6392a52eb409e

@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:

https://github.com/discourse/discourse/pull/7886

여기서 일반적인 제 추천은 플러그인 개발자로서 제약 조건을 적절히 강제하기 위해 마이그레이션에서 항상 인덱스를 추가해야 한다는 것입니다. 사실 요즘 대부분의 플러그인은 절대적으로 필요한 경우가 아니면 커스텀 필드를 피하고, 훨씬 더 쉽게 추론할 수 있는 커스텀 테이블 사용을 선호합니다. 이 특정 경우를 위해 필요한 인덱스는 다음과 같습니다:

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

코어에서 여기서 더 해야 할 일이 무엇인지 확실하지 않습니다. 커스텀 필드의 개편을 고려해 보았지만, 다소 우려가 있습니다. 제가 고려하고 있는 것 중 하나는 커스텀 필드에서 배열 지원을 단순히 제거하는 것입니다. 왜냐하면 지난 수년간 커스텀 필드의 배열 지원은 막대한 양의 문제를 일으켜 왔기 때문입니다.

이 주제를 다시 올리는 것이라 죄송합니다. 하지만 기존 값을 업데이트할 때 심볼 인덱스(예: custom_fields[:hello])를 사용하는 것이 그 조건 중 하나입니다. 이 경우 값을 업데이트하는 대신 새로운 필드가 추가되어 배열이 반환됩니다. 제 생각에는 이것이 유일한 조건일 수 있습니다.

이로 인해 발생한 부수 효과를 확실히 수정할 수 있을 것입니다.