Reputation: 798
I have a collection of posts that are within categories and subcategories using a belongs_to
association. Additionally, the posts have a belongs_to
relationship with my state and city models.
I am limiting the display of the posts at the controller to those belonging to the respective location (i.e. city or state) by using a request.subdomain
check on the subdomain in the URL. This works perfectly for everything except search using Tire/ElasticSearch.
For some reason I can't get Tire to limit search results to the posts belonging to a specific location. I've tried getting the subdomain into the model using a cater_accessor :request_subdomain
in the model and adding a before_filter
in the controller where @city_or_state
is location associated with the subdomain.
def set_request_subdomain
Post.request_subdomain = @city_or_state if !@city_or_state.nil?
end
Here's my model:
def self.search(params)
tire.search(load: true, page: params[:page], per_page: 10) do
query { string params[:query], default_operator: "AND" } if params[:query].present?
filter :terms, :published => [true]
filter :terms, :request_subdomain => [:city_subdomain || :state_subdomain]
end
end
def to_indexed_json
to_json(methods: [:city_name, :city_subdomain, :state_name, :state_subdomain])
end
def city_name
self.city.name
end
def city_subdomain
city.subdomain.titleize
end
def state_name
self.state.name
end
def state_subdomain
state.subdomain.titleize
end
I need the search to limit results by the location (i.e. subdomain).
What am I missing here?
UPDATE: I have followed this railscast and been able to get Facets to work... I'm thinking maybe I can limit the items searched based on a Facet (i.e. without a user selecting a Facet as in the railscast), but I haven't been able to get that working.
Any ideas?
Upvotes: 2
Views: 1106
Reputation: 84114
This
filter :terms, :request_subdomain => [:city_subdomain || :state_subdomain]
is back to front - the left hand side of the hashrocket should be a property of your tire index, and the right hand side that value it should match. Secondly, this is just plain ruby so
[:city_subdomain || :state_subdomain]
evaluates to just :city_subdomain
, the 'or' doesn't magically make its way into the query logic
You want instead to say that either the :city_subdomain
matches a certain value or the state_subdomain
matches. You could do that with something like this, assuming that subdomain
was a local variable or argument to your search method (far preferable to a class level variable)
filter :or, [
{:term => {:city_subdomain => subdomain}},
{:term => {:state_subdomain => subdomain}}
]
Upvotes: 1
Reputation: 2341
If you're looking for the number of results to be limited, you can always run some ruby inside of your search block, and use the size
and from
methods.
search = Tire.search(Location.index_name) do |s|
s.query do |q|
q.string "las vegas"
end
# Best used for pagination
s.size 25 # limit 25 results
s.from 0 # start at the beginning.
end
I'm not sure exactly what you'd need, but you could always do something like
if something.nil?
s.size 0
else
s.size 25
end
That would be changing the limit based on some condition.
Upvotes: 0