エラー: 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') を使用すると、internal server error(内部サーバーエラー)が発生します。ログには以下のように表示されます。

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) や、トピックを操作する他のプラグインをご覧になるか、あるいは Discourse コア内で HasCustomFields を確認してみてください。

ありがとうございます、そういう状況だったのですね。もしかすると、そのモデルとの結合(join)が必要になるかもしれません(Railsの知識を少し思い出さないと)。以下のようなコードを試してみたのですが:

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

エラーが発生しました:ActiveRecord::ConfigurationError (Can't join 'Topic' to association named 'topic_custom_field'; perhaps you misspelled it?)

正しい構文についてご教示いただけませんでしょうか。

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')

その後、tcf(一致するすべての結果の配列)から topic_id などを取得できます。topic_id がわかっている場合は、一意性を保証するために必要な 3 つの条件を指定して TopicCustomField.find_by(<3 つの条件>) を実行することも可能です。

いいですね。情報ありがとうございます。試してみます。

「いいね!」 1