Ruby on Rails Sunspot solr condition on included association - ruby-on-rails

I'm trying to search Products using solr and it's working well. Except that I want to restrict the suppliers, associated with Products by has_and_belongs_to_many, using the status field in Supplier model being 0 or 1.
My models are:
"Product.rb"
has_and_belongs_to_many :suppliers, :class_name => 'Company'
searchable do
text :name
text :brand
text :description
end
"Company.rb"
attr_accessible :status
has_and_belongs_to_many :products
For search I'm using:
#search = Product.search(:include => :suppliers) do
fulltext params[:s]
with :status, 1 # This gives error as status is not a field in Product
end
How can I include only those suppliers with status 1?

You're missing the status in the searchable
searchable do
text :name
text :brand
text :description
boolean :status
end

Related

How to search in has_many association using Sunspot/Solr?

Here is what my initial searchable block looks like in my User model:
searchable do
text :name
integer :sport_ids, multiple: true do
sports.map(&:id)
end
integer :position_ids, multiple: true do
positions.map(&:id)
end
integer :city_id
integer :school_id
string :state
end
How do I search by has_many associations? I need it to return each Athlete who has a specified ID in their sports or sport_positions. So if someone selects "Basketball" from a dropdown, ID of 2 is passed to my search method and it needs to return Athletes who have sport_id of 2 in their collection of sport_ids. Here is how sports and sport_positions are declared in the User model:
has_and_belongs_to_many :positions, :class_name => "SportPosition", :join_table => "user_sport_positions", :uniq => true
has_many :sports, :through => :user_sports, order: "user_sports.created_at", class_name: "Sport"
has_many :user_sports
:::EDIT:::
This worked for a minute after I reindexed, then all of a sudden I started getting this error:
Sunspot::UnrecognizedFieldError (No field configured for Athlete with name 'sport_ids'):
app/models/search.rb:12:in `block in execute'
here is my Search model:
class Search < ActiveRecord::Base
attr_accessible :coach_id, :sport_id, :gpa_min, :gpa_max, :sport_position_id,
:classification, :city_id, :state, :school_id, :athlete_name
belongs_to :coach
def self.execute(params, page = nil)
Sunspot.search(Athlete) do |query|
query.with :public, true
query.with :removed_from_listing, false
query.fulltext params[:athlete_name] unless params[:athlete_name].blank?
query.with :sport_ids, params[:sport_id] unless params[:sport_id].blank?
query.with :position_ids, params[:sport_position_id] unless params[:sport_position_id].blank?
query.with(:state).equal_to(params[:state]) unless params[:state].blank?
query.with(:classification).equal_to(params[:classification]) unless params[:classification].blank?
query.with :city_id, params[:city_id] unless params[:city_id].blank?
query.with :school_id, params[:school_id] unless params[:school_id].blank?
query.with(:current_gpa).between(params[:gpa_min]..params[:gpa_max]) unless params[:gpa_min].eql?("0.0") && params[:gpa_max].eql?("5.0")
query.paginate page: page unless page.blank?
end
end
end
NOTE: To make this even more strange, I have a field called "recruit_year" that is an integer attribute. I was getting the same error on this field saying "No field configured" blah blah. That error usually only happens on text fields if you try to do a comparison like equal_to or treat it like a string.
Help?
This works fine, the problem was STI. I had an Athlete block that was overriding the User block.

How to display associated model's attribute in Active Admin index with belongs_to/has_many relationship (Rails 3.2/Active Admin)

I'm building a daily deal Rails app to learn RoR.
I am facing a problem for the past few hours : i can't get a model's attribute of an other associated model on active admin. Let me show you exactly the problem :
I have two models: Brand (i.e the brand of the deal) and Deal. A deal belongs to a Brand but a Brand can have many Deals.
models/deal.rb is like this:
class Deal < ActiveRecord::Base
belongs_to :brand
and we have models/brand.rb:
class Brand < ActiveRecord::Base
has_many :deals
attr_accessible :name
And i did the t.belongs_to in my migrations so this is ok.
In Active Admin's Deals' create form , i type, as admin, which brand the deal is associated with:
admin/game.rb
ActiveAdmin.register Deal do
# -- Form -----------------------------------------------------------
form do |f|
f.inputs "Brand (i.e. client)" do
f.input :brand_id, :label => "Select a brand:", :as => :select, :collection => Brand.all
end
it works great, and i can create Deals with a certain brand.
but I CAN'T manage to display the NAME of the Brand in my list of Deals:
ActiveAdmin.register Deal do
index do
selectable_column
# id_column
column :title
column :deal_amount
column :brand do |deal|
link_to deal.brand.name
end
...doesn't work.
How can I do that ?
I tried everything but i basically don't know how to fetch the name of a Brand given it matches the brand_id in the Deal's table.
Any help appreciated.
show do |f|
panel "Subject" do
attributes_table_for f, :name, :description, :is_visible
end
panel "Pages in List View" do
table_for(f.pages) do |page|
column :name
column :permalink
column :is_visible
end
end
panel "Pages in View " do
div_for(f.pages) do |page|
panel page.name do
attributes_table_for page, :name, :description, :is_visible
end
end
end
end
end
You can do nested relations in same style as parent model
A couple things seem missing:
class Deal < ActiveRecord::Base
belongs_to :brands, foreign_key: :brand_id, class_name: 'Brand'
end
This is assuming that you mean partner to be a Brand and your schema uses brand_id for that relationship.
In your form, you can simply use:
form do |f|
f.inputs "Brand (i.e. client)" do
f.input :partner, label: 'Select a brand:'
end
end
Your link_to call won't actually link to a url the way you have it.
column :brand do |deal|
link_to deal.partner.name, admin_brand_path(deal.partner)
# or simpler
auto_link deal.partner
end
I would highly recommend trying to be consistent in your naming, as it will make things a lot less confusing and will require less code to make things work. i.e.
class Deal < ActiveRecord::Base
belongs_to :brand
end
f.input :brand, label: 'Select a brand:'
auto_link deal.brand
And your DB column can still be named brand_id.

sort by association field in sunspot

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

Sunspot solr in rails need help to perform some query

I have a model User and Listing in my rails app. User has many listings and listing belongs to user. I also have a attribute name rating in user table. What I want is to search the keyword in Listing model and order it based on rating attribute of User model.
This is what I have in Listing model
searchable do
text :title, :default_boost => 3
text :description, :default_boost => 2
integer :category_id, :references => Category
integer :subcategory_id, :references => Subcategory
string :zipcode
time :created_at
double :user do
user.rating
end
end
And this is how I am trying to search
#search = Sunspot.search(Listing) do
keywords params[:q] do
fields :title
end
order_by THIS IS WHERE I NEED HELP
paginate :page => params[:page], :per_page => 20
end
You will need to add the keyword and rating attributes to the listing searachable method.
class Listing < ActiveRecord::Base
belongs_to :user
searchable do
text :keyword
integer :rating { user.rating }
end
end
Then in your search action in your controller
Listing.search do
fulltext params[:q]
order_by :rating, :desc
end
See http://sunspot.github.com/ for more examples.
Looking at your code, you need to change in your searchable method
double :user do
user.rating
end
to
double :rating do
user.rating
end

SunSpot Geosearching through assocation

class Office < ActiveRecord::Base
has_many :users
searchable do
text :name
location :coordinates do
Sunspot::Util::Coordinates.new(latitude, longitude)
end
end
end
class User < ActiveRecord::Base
belongs_to :office
searchable do
text :name, :default_boost => 2
text :description
end
end
With this kind of a setup, how can I search using SunSpot (on Solr) on Rails for a user within a given lat/long? For example, I want to be able to do this:
#search = User.search() do
fulltext(params[:q])
with(:coordinates).near(#lat, #long, :precision => 5)
end
The following works just fine:
#search = Office.search() do
fulltext(params[:q])
with(:coordinates).near(#lat, #long, :precision => 5)
end
What is the best way to accomplish this given that the lat/long for each User really lives in the Office class?
The office association should be in scope inside your User's searchable block.
Given that, here's what I would start with (untested, off the top of my head, etc):
class User < ActiveRecord::Base
belongs_to :office
searchable do
text :name, :default_boost => 2
text :description
location :coordinates do
Sunspot::Util::Coordinates.new(office.latitude, office.longitude)
end
end
end
Fetching values for associated objects in a block like this is actually a pretty common pattern for handling denormalization with Sunspot.

Resources