I am trying to set search on a model that has a lot of different associations. I am starting with the belongs_to associations. I am able to search on the name field of the Product model successfully but the when I perform a search on what would be in the associated models I just get the default results.
What am I doing wrong?
Any help would be much appreciated.
#Product Model
Class Product < ActiveRecord::Base
searchable do
text :name
integer :store_id, :references => Store.name
text :store do
Store.all.map { |store| store.name }
end
end
end
#product controler
def search
#search = Sunspot.search(Product) do
fulltext params[:search] do
fields(:name, :store)
end
end
#products = #search.results
end
#Store Model
searchable do
text :name
end
Class Product < ActiveRecord::Base
belongs_to :store
searchable do
text :name
index :store do
index :name
end
integer :store_id # do you really need this? I think not.
end
end
Don't forget to reindex after each change in your models.
EDIT: You don't need to index the Store class by itself, unless you plan to search on it.
Related
I'm attempting to use ransack to search for an attribute on a has_one association in a model.
Currently in my model I have:
class SurveyResponse < ActiveRecord::Base
belongs_to :course_schedule
has_one :instructor, through: :course_schedule
has_one :instructor_user, through: :instructor, foreign_key: "user_id", source: :user
I want to search by instructor_user's name in my survey response view. Should I be doing this with a ransacker? My understanding of Arel is very limited, but can I do something like this? (I know this doesn't work as it is..)
def self.ransackable_attributes(auth_object)
[
'created_at',
'instructor_user_name'
]
end
ransacker :instructor_user_name, type: :string do
Arel.sql('string(survey_responses.instructor_user.last_name)')
end
In my survey response controller I currently have:
def index
#search_associations = [:course, :user]
#q = SurveyResponse.where(corporation_id: #corporation.id).ransack(params[:q])
#q.build_condition
#survey_responses = #q.result.includes(:course, :user, :course_schedule, :instructor, :instructor_user).order(created_at: :asc)
#survey_responses = paginate(#q)
end
Any help, resources, and guidance would be greatly appreciated.
I don't think you need a ransacker specifically. I believe in your view, inside a search_form_for you just simply could do:
<%= f.search_field :instructor_user_name %>
Also, in your controller instead of #survey_responses = paginate(#q) I think you need #survey_responses = paginate(#survey_responses) so you can paginate the responses not the ransack object (could be wrong on this based on what pagination gem you're using).
I have one to many association between jobs and companies and i have implemented a search form for jobs using sunspot gem but i want when i search a company_name i have all jobs results of the company searched how can i do this
this is my job model
class Job < ActiveRecord::Base
belongs_to :company
searchable do
text :job_title, boost: 4
text :profile_recherche
end
this is my company model
class Company < ActiveRecord::Base
has_many :jobs
this is my jobs search controller
def search
#jobs = Sunspot.search(Job) do
keywords params[:query]
fulltext params[:query]
paginate(page: params[:page], per_page: 1)
end.results
respond_to do |format|
format.html { render :action => "index" }
end
end
It sounds like you want to search Jobs by job_title, profile_reserche, and company.name. If I'm guessing what you want correctly, changing your searchable block like so should do it:
class Job < ActiveRecord::Base
belongs_to :company
searchable do
text :job_title, boost: 4
text :profile_recherche
text :company_name do
company.name
end
end
end
One caveat here is that if you have overlap in tokens, stems, n-grams, whatever between these various fields, you could have some interesting search results.
How do I search with associations and through with sunspot?
class StaticController < ApplicationController
def search
#search = Sunspot.search Business, Service do
fulltext params[:q]
paginate :per_page => 10
order_by_geodist(:location, *Geocoder.coordinates(params[:loc]))
end
#biz = #search.results
end
class Business < ActiveRecord::Base
attr_accessible :name
has_many :services, :through => :professionals
searchable do
text :name #name in business column
# how to do I get the services?
end
end
class Service < ActiveRecord::Base
attr_accessible :service
belongs_to :professional
end
class Professional < ActiveRecord::Base
belongs_to :business
has_many :services, as: :servicable
end
In the view, I have this (lots of looping)
<%= #biz.each do |b| %>
<%= b.name %>
<!-- looping through professionals model -->
<% b.professionals.each do |prof| %>
<!-- looping through services model -->
<% prof.services.each do |s| %>
<%= s.service %>
<% end %>
<% end %>
<% end %>
This works if I search for a name that is within the business model, but what if I'm searching through a term that's in the Service model? It won't display correctly because my view is only coming from the business side. How do I make it so the business name will pop up if I search through Service model?
Thanks
You will need to make additional indexes for the associated models in the calling model to make this happen. For example:
class Business < ActiveRecord::Base
attr_accessible :name
has_many :services, :through => :professionals
searchable do
text :name #name in business column
text :services do # this one for full text search
services.map(&:service).compact.join(" ")
end
string :services , :multiple => true do #this one for exact searches
services.map(&:service).compact
end
end
end
After that you can do queries like:
Bussines.search do
with(:services, "some_service")
end.execute.results
Now you no longer have to do join on mysql tables to fetch data. You can just fetch data from the solr. This is one of biggest advantages of solr.
I hope this makes it clear. Fell free to drop a comment if you need more details.
Example:
I have the following:
class Person < ActiveRecord::Base
has_many :educations
end
class Education < ActiveRecord::Base
belongs_to :school
belongs_to :degree
belongs_to :major
end
class School < ActiveRecord::Base
has_many :educations
# has a :name
end
I want to be able to return all people who went to a specific school so in my PeopleController#index I have
#search = Person.search do
keywords params[:query]
end
#people = #search.results
How do I create the searchable method on the Person model to reach down into school? Do I do something like this:
searchable do
text :school_names do
educations.map { |e| e.school.name }
end
end
which I would eventually have to do with each attribute on education (degree etc) or can I make a searchable method on Education and somehow "call" that from Person.searchable?
Thanks
It would be best if you keep the declaration of all the indexed fields for an specific model in the same place.
Also, you were doing a good job indexing :school_names, just do the same thing for the rest of the associations fields' that you want to index.
In my app I am using Sunspot for a fulltext search. The problem is that I want to have sorting by association model field. In my case:
class Movie < ActiveRecord::Base
attr_accessible :description, :genre, :name
has_many :premieres
end
and my Premier model has:
belongs_to :movie
Searching by movie name is done by defining the method:
def movie_name
movie.name
end
but when I try to do:
order_by :movie_name, :asc
It says:
No field configured for Premiere with name 'movie_name'
How do I make this sorting available?
you can do it like this
searchable auto_index: true do
text :movie_name do
if self.movie.present?
self.movie.name
end
end
end
then you can use
order_by :movie_name, :asc