簡體   English   中英

pg_search:使用動態方法作為反對參數

[英]pg_search: Using a dynamic method as the against parameter

根據這個問題的接受答案,您應該能夠使用實例方法的返回值作為反對參數...

class Car < ActiveRecord::Base
  include PgSearch
  multisearchable :against => [:name, manufacturer_name]
  belongs_to :manufacturer

  def manufacturer_name
   manufacturer.name
  end
end

但是,當我嘗試在一個干凈的應用程序(以排除真實應用程序中的沖突代碼)中使用上述模型,db等創建時,我得到一個未定義的局部變量或方法錯誤 - 我錯過了什么?

好吧,簡短的故事是鏈接帖子中提供的代碼沒有也不能正常工作,好像你不能用這種方式引用方法(實例或其他方式) - 這是有意義的:類需要按順序編譯為了使該方法可用,但不能,因為它需要所述方法才能進行編譯。

為了實現我最初的嘗試(沒有覆蓋pg_search),我采取了以下步驟:

首先,反對聲明應使用符號代替原始方法調用。

multisearchable :against => [:name, :manufacturer_name]

這樣做,當保存對象時,將使用manufacturer_name方法創建/更新PgSearch :: Document。 但是,如果您嘗試使用以下錯誤重建搜索索引,則會中斷:

ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR:  column cars.manufacturer_name does not exist
  LINE 5: ...sce("cars".name::text, '') || ' ' || coalesce("cars"...
                                                           ^
: INSERT INTO "pg_search_documents" (searchable_type, searchable_id, content, created_at, updated_at)
  SELECT 'Car' AS searchable_type,
         "cars".id AS searchable_id,
         (
           coalesce("cars".name::text, '') || ' ' || coalesce("cars".manufacturer_name::text, '')
         ) AS content,
         '2014-01-29 14:08:00.190767' AS created_at,
         '2014-01-29 14:08:00.190767' AS updated_at
  FROM "cars"

要解決此問題,請覆蓋由Multisearch模塊添加的rebuild_pg_search_documents類方法,以構建動態SQL插入查詢,而不是回復現有的純SQL INSERT INTO table_name (columns) SELECT etc查詢:

def self.rebuild_pg_search_documents
  cars = Car.all

  query_str = 'INSERT INTO pg_search_documents (searchable_type, searchable_id, content, created_at, updated_at) VALUES'

  cars.each do |car|
    query_str += "('Car', #{car.id}, '#{car.name} #{car.manufacturer_name}', NOW(), NOW())"

    query_str += ', ' unless car == cars.last
  end

  query_str += ';'

  connection.execute query_str
end

希望這會幫助別人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM