Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

multi search by associated model #70

Closed
EnotPoloskun opened this Issue Oct 17, 2012 · 11 comments

Comments

6 participants

Hello, I have a problem with multi search by associated model. I did everything what was in readme.
in my model i have

    has_one :profile

    def last_name
      profile.last_name
    end

    include PgSearch
    multisearchable :against => [:last_name]

and when I try to rebuid documents

PgSearch::Multisearch.rebuild(User)

I am receiving an error

ActiveRecord::StatementInvalid: PG::Error: ERROR:  column users.last_name does not exist
LINE 5:            coalesce("users".last_name::text, '')
                            ^
: INSERT INTO "pg_search_documents" (searchable_type, searchable_id, content, created_at, updated_at)
  SELECT 'User' AS searchable_type,
         "users".id AS searchable_id,
         (
           coalesce("users".last_name::text, '')
         ) AS content,
         '2012-10-17 12:07:29.180275' AS created_at,
         '2012-10-17 12:07:29.180275' AS updated_at
  FROM "users"

What i am doing wrong?

Collaborator

nertzy commented Oct 17, 2012

What version of pg_search are you running? I believe the latest version has a fix for this specific issue.

I am using pg_search-0.5.7

Is this progressing? Has it ever worked in any version of pg_search?

+1. The documentation seems to indicate this is possible, but it appears to only work for existing db columns, not calculated string values.

Aha: solved this. What's not clear is if you use a method as a value to index, rather than a DB column, then you'll need to override self.rebuild_pg_search_documents. The example given:

def self.rebuild_pg_search_documents
    find_each { |record| record.update_pg_search_document }
end

works just fine. It just wasn't clear this was necessary for this to work.

Nice, I will try that out!

I'm seeing the same issue. Can you say exactly what needs to be overrride and how? And also where to put the code?

I'm guessing

def self.rebuild_pg_search_documents
    find_each { |record| record.update_pg_search_document }
end

needs to go somewhere?

@philipliou - if you want to index method-results of an object in a Rails application, rather than just DB fields, then you need to define your own rebuild_pg_search_documents method for a class. So, in the ActiveRecord class which has methods you wish to index, just include the class method rebuild_pg_search_documents as described above. then, every time you regenerate the multisearch indexes for your application, dynamically generated fields will also be included.

Does that help?

@infovore Yup, that worked. Thanks! Maybe a somewhat related question...is it possible to index against a method that returns an array? For example, I have a User model and each user can have multiple Skills.

@philipliou no idea. Although: if skills are stored as an array, why not just index Users against a space-separated list of Skills - ie, turn the Array into a String. That'd probably work fine.

As a workaround, you can call multisearchable with something like this:

multisearchable :against => [:last_name], :if => :persisted?

or any other method that returns true. It will make pg_search to skip the SQL and use

find_each { |record| record.update_pg_search_document }

internally.

nertzy added a commit that referenced this issue May 4, 2015

Don’t use SQL to rebuild dynamic multisearchable
Iterate over each record with `find_each` instead.

Fixes #70

@nertzy nertzy closed this in #244 May 4, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment