Skip to content

Instantly share code, notes, and snippets.

@steveklabnik
Created October 21, 2013 16:53
Show Gist options
  • Save steveklabnik/7087076 to your computer and use it in GitHub Desktop.
Save steveklabnik/7087076 to your computer and use it in GitHub Desktop.
Halp!
class Foo
has_many :tags
has_many :states
# q is hash: { "tags" => "ruby", "states" => "open" }
def self.search(q)
# wat do?
end
end
# search should return a relation that scopes everything to the terms
# the values 'ruby' and 'open' are in the 'name' attribute of the Tag and State model.
@saturnflyer
Copy link

shot in the dark. didn't run it

def search(q)
  tags.where(name: q['tags'].split).merge(states.where(name: q['states'].split))
end

@liveh2o
Copy link

liveh2o commented Oct 21, 2013

We typically avoid joins and just do an additional query (joins are expensive in our data set). Building on the scope example:

scope :by_tag, ->(*tags) {
  ids = Tag.where(:name => tags.flatten).uniq.pluck(:foo_id)
  where(:id => ids)
}
scope :by_state, ->(*states) {
  ids = State.where(:name => states.flatten).uniq.pluck(:foo_id)
  where(:id => ids)
}

def self.search(query)
  records = all
  records = records.by_tags(query["tags"].split(' ')) if query["tags"].present?
  records = records.by_states(query["states"].split(' ')) if query["states"].present?
  records
end

If joins aren't a concern, then this could be easily tweaked, but I prefer the pluck pattern.

@steveklabnik
Copy link
Author

@coreyword yes, the real search method takes a string, and i do some processing to get it into the hash form. figured i'd just ignore those details here though.

@steveklabnik
Copy link
Author

Thanks so much everyone!

@litch
Copy link

litch commented Oct 21, 2013

I'd love to know what you settle on. In a system of mine I do something like @subdigital's solution...

@pier-oliviert
Copy link

I prefer what you did @ https://gist.github.com/steveklabnik/6705873

I've tried like 20 different things with search module and stuff in the past year and never was satisfied by it. I think searching would be much easier to build in an abstract way if it would be possible to list the scopes for an ActiveRecord::Base. Is there a reason why it's not available?

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