Search code examples
ruby-on-railspostgresqlsearchpg

ROR Search virtual fields


I am just adding search to my project to be able to find people by name. but on my db i have first_name and last_name but if someone searches for a full name like Joe Doe no result matches

#model 
class Person < ActiveRecord::Base
  def full_name
    (self.first_name + ' ' + self.last_name).titleize
  end
end

#controller 
class PeoplesController < ApplicationController
  expose(:peoples){
    if params[:search]
      People.where(
        "first_name ILIKE ?
         OR last_name ILIKE ?
         ", params[:search], params[:search]
      )
    else
      People.all
    end
  }
end

Again if someone searches a first_name it comes back with results, last_name it comes back with results but not for a full name

and if i try to add full_name to the query i get column "full_name" does not exist

Thanks for the help


Solution

  • A virtual field is not on database-level. You can't do database-based search without explaining what that virtual field is to the database.

    The definition of your field is essentially a list of columns it consists of. Since you are using PostgreSQL, you could leverage its full-text searching capabilities by using pg_search. It's well able to search by multiple columns at once.

    In fact, in the docs there is an example of how to do it that almost exactly matches your case. I literally just copy-pasted it here. Go figure.

    # Model
    class Person < ActiveRecord::Base
      include PgSearch
      pg_search_scope :search_by_full_name, :against => [:first_name, :last_name]
    end
    
    # Example code for the Rails console
    person_1 = Person.create!(:first_name => "Grant", :last_name => "Hill")
    person_2 = Person.create!(:first_name => "Hugh", :last_name => "Grant")
    
    Person.search_by_full_name("Grant") # => [person_1, person_2]
    Person.search_by_full_name("Grant Hill") # => [person_1]
    

    Is that sort of thing worth an extra dependency, is up to you. If you find yourself in situation of constructing many complicated searches, this might help.