오류: PG::UndefinedColumn. 사용자 지정 필드가 컬럼을 생성하지 않음

토픽 커스텀 필드가 topics 모델에 컬럼을 추가하나요? 추가되지 않는다는 오류가 발생하고 있어서 어떻게 해야 할지 고민 중입니다.


개발 환경에서 여기의 가이드를 따라 토픽 커스텀 필드를 생성했습니다. 이를 fun_level이라고 부르겠습니다. 커스텀 필드는 개발 환경에서 정상적으로 생성된 것 같습니다. 커스텀 필드를 추가한 후 생성한 토픽을 가져오기 위해 ajax("/t/112.json")와 같은 ajax 호출을 수행하면, 입력한 값이 포함된 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) 또는 주제(topic)를 조작하는 다른 플러그인을 참고해 보시길 권합니다. 아니면 discourse 코어에서 HasCustomFields를 찾아보시는 것도 좋습니다.

감사합니다. 무언가 그런 일이 일어나고 있는 건 아닌지 짐작하고 있었거든요. 그래서 아마 해당 모델과 조인(join)을 해야 할 것 같습니다(정말 레일즈를 다시 꺼내야겠네요). 다음과 같은 코드를 시도해 보았는데요:

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 등의 값을 가져올 수 있습니다(tcf는 모든 일치 항목의 배열입니다). topic_id를 알고 있다면 TopicCustomField.find_by(<고유성을 보장하기 위한 세 가지 조건>)를 사용할 수 있습니다.

좋아요. 정보 감사합니다. 직접 해보고 테스트해볼게요.