Ошибка: PG::UndefinedColumn. Пользовательское поле не создает колонку

Добавляют ли пользовательские поля тем столбец в модель тем? У меня возникает ошибка с сообщением «нет», и я пытаюсь разобраться, что с этим делать.


Я создал пользовательское поле для темы в среде разработки, следуя этой инструкции. Назовём его fun_level. Поле, похоже, успешно создано в среде разработки, потому что, если я делаю AJAX-запрос для получения созданной мной темы после добавления этого поля — например, ajax("/t/112.json") — всё работает: возвращаются данные темы, включающие поле fun_level со значением, которое я ввёл.

Но теперь мне нужно найти способ программно получить все темы с определённым значением пользовательского поля (например, получить список всех тем, где fun_level = ‘super-duper-fun’).

Я рассматривал возможность использования ajax("/search") для этого, но пока не смог заставить это работать.

Другой метод, который я придумал, — использовать классический Rails: создать контроллер и, при переходе по определённому пути (/fun_levels/:fun_level), вызвать следующий метод show:

  def show 
   respond_to do |format|
      format.json { render json: Topic.where(fun_level: 'super-duper-fun') }
    end
  end

Затем я вызываю ajax("/fun_levels/super-duper-fun.json")

Эта стратегия с методом show контроллера и AJAX-запросом работает, если я ищу темы по id, заголовку и т.п. Но когда я использую код выше — Topic.where(fun_level: 'super-duper-fun') — возникает внутренняя ошибка сервера. В логах указано:

ActiveRecord::StatementInvalid (PG::UndefinedColumn: ERROR: column topics.fun_level does not exist LINE 1: ... "topics" WHERE "topics"."deleted_at" IS NULL AND "topics"."...

Есть ли способ получить темы на основе пользовательского поля с помощью метода контроллера, как я показал выше? (например, мой вариант: { render json: Topic.where(fun_level: 'super-duper-fun') })?

Существует модель TopicCustomField. Вам, возможно, стоит обратить на неё внимание. Посмотрите, например, на Topic List Previews (legacy) или на другой плагин, который работает с темами. Или, возможно, найдите HasCustomFields где-нибудь в ядре Discourse.

Спасибо — я уже начал догадываться, что дело, скорее всего, в этом. Значит, возможно, мне нужно будет сделать join с этой моделью (придется хорошенько освежить знания по Rails). Я пробовал что-то вроде этого:

Topic.joins(:topic_custom_field).where(fun_level: 'super-duper-fun')

но получаю ошибку: ActiveRecord::ConfigurationError (Не удалось выполнить join для 'Topic' по ассоциации с именем 'topic_custom_field'; возможно, вы допустили опечатку?).

Есть какие-нибудь идеи относительно правильного синтаксиса?

Я не могу найти TopicCustomField прямо сейчас (но я же сказал вам, где искать! :wink)

Вот что у нас есть:

[4] pry(main)> CategoryCustomField.last
=> #<CategoryCustomField:0x000055be74a00bd0
 id: 2,
 category_id: 8,
 name: "enable_accepted_answers",
 value: "true",
 created_at: Mon, 26 Apr 2021 15:45:07.862617000 UTC +00:00,
 updated_at: Mon, 26 Apr 2021 15:45:07.862617000 UTC +00:00>

Так что примерно так:

tcf=TopicCustomField.where(name: 'fun_level', value: 'super-duper-fun')

Затем вы можете получить topic_id и прочее из tcf (это массив всех совпадений). Если вы знаете topic_id, вы можете выполнить TopicCustomField.find_by(<all three things to make it unique>).

Круто. Спасибо за информацию. Я попробую поэкспериментировать с этим.