Error: PG::UndefinedColumn. Custom field not creating column

AI-generated summary

A user, JQ331, is experiencing an error (PG::UndefinedColumn) when trying to retrieve topics based on a custom field (fun_level) using a controller method. The issue is that the custom field does not add a column to the topics model.

JQ331 attempted to join the TopicCustomField model but encountered an error. pfaffman suggested using the TopicCustomField model and provided an example of how to access it.

pfaffman further assisted by providing a query example using TopicCustomField.where to retrieve custom fields by name and value. This can be used to get the topic_id and then retrieve the corresponding topic.

JQ331 plans to experiment with the suggested approach to resolve the issue.

Do topic custom fields add a column to the topics model? I am getting an error saying no, and I’m trying to figure out what to do about it.


I have created a topic custom field in development, following here. Let’s call it fun_level. The custom field seems to be successfully created in development, bc if I do an ajax call to get back a topic I have created after adding the custom field–like ajax("/t/112.json")–it works: the topic data comes back showing the field fun_level with the value I entered.

But now I need to find a way to programmatically retrieve all topics with a certain value for the custom field (eg, get a list of all topics where fun_level = ‘super-duper-fun’).

I’ve considered doing an ajax("/search") for that, but I haven’t gotten it to work yet.

Another method I thought of was to use classic rails: create a controller, and when I go to a certain path (/fun_levels/:fun_level), call the following show method:

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

Then, I call ajax("/fun_levels/super-duper-fun.json")…

This controller show method/ajax call strategy works if I am finding topics based on an id, title, etc. But when I use the above code-Topic.where(fun_level: 'super-duper-fun)–it sends an internal server error. And the logs say:

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

Is there a way to get back topics based on a custom field using a controller method, like I’ve provided above? (like my: { render json: Topic.where(fun_level: 'super-duper-fun') })

There is a TopicCustomField model. You want that. Maybe have a look at Topic List Previews (legacy) or some other plugin that mucks with topics. Or maybe see HasCustomFields somewhere in discourse core.

Thanks–I was starting to figure something like that must be going on. So perhaps I’d need to do a join with that model (really having to dust off my rails here). I’ve tried something like this:

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

but I get the error: ActiveRecord::ConfigurationError (Can't join 'Topic' to association named 'topic_custom_field'; perhaps you misspelled it?)

Any ideas on the right syntax?

I can’t find a TopicCustomField this instant (but I told you where to look! :wink)

Here’s this:

[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>

So something like

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

Then you can get the topic_id and such from tcf (it’s an array of all matches). If you know the topic_id you could do a TopicCustomField.find_by(<all three things to make it unique>).

Cool. Thanks for the info. I’ll experiment with it.