Searching issue with the rails-sunspot gem - ruby-on-rails-3

I'm very new to Solr and the Rails Sunspot gem, but it looks very promising for complex searching on a big database.
What I'm trying to do is allow a model in my rails app to be searched on a few fulltext columns and then a collection of its "filters" (which are just a has_and_belongs_to_many association of names).
I tried setting up my model search block as follows
self.searchable do
text :name, :boost => 5
text :description, :instructions
text :filters do
filters.map(&:name)
end
end
And my controller looks like so:
#search = ModelName.search do
keywords params[:q].to_s
end
However, I cannot seem to produce any results based on keywords found in the filters association. Am I doing something wrong? This is all very new to me.

When you initially set up your classes for search, you need to reindex the data into Solr. Have you done that? If not:
rake sunspot:reindex

Related

Activeadmin and Formtastic with HStore column

I am unable to edit or add a new model in activeadmin that has an HStore column due to the following error.
Unable to find input class for hstore
How can I get activeadmin and formtastic to play nice with my HStore column? This question has been asked but I cannot find a definitive answer that allows for adding and editing of the hstore field.
I have used these references so far
With latest activeadmin (which uses ransack instead of meta_search) it's possible to define a custom ransacker for hstore field in a model:
class Room < ActiveRecord::Base
store_accessor :options, :amenities
ransacker :amenities do |parent|
Arel::Nodes::InfixOperation.new('->', parent.table[:options], 'amenities')
end
end
Then it can be used in activeadmin for filtering:
ActiveAdmin.register Room do
filter :amenities_eq, label: 'Amenities', as: :select # ...
end
Filter activeadmin with hstore
and
https://github.com/gregbell/active_admin/issues/2032
For anyone who happens to stumble across this, I was able to use the activeadmin_hstore_editor gem for this purpose, which gives a way to input arbitrary json into an input field.

How can I query a rails 3 app efficiently?

I have a search form that queries one table in the database but there are many parameters (language, level, creator etc). The code below works provided the fields in question are filled in but I want to change it to:
a) add more parameters (there are several);
b) allow for a field to be empty
Here's the code in the controller:
#materials = Material.find(:all, :conditions => {:targ_lang => params["targ_lang"],
:inst_lang => params["inst_lang"],
:level => params["level"]})
Totally new to this I'm afraid but a lot of the documentation suggests I should be using "where".
Since Rails 3 you can use the where() function:
#materials = Material.where(targ_lang: params["targ_lang"], inst_lang: params["inst_lang"], level: params["level"])
Also, you could take a look at scopes
These allow you to set what you want to do in the model and call it in the controller for example:
class Material < ActiveRecord::Base
scope :active, where(active_state: true)
end
Then in the controller you do something like:
#active_materials = Material.active
This can be useful if you are joining several models and want to keep your controllers less messy.
To conclude, like #RVG said, seachlogic is quite useful as well as, there are others like Sphinx and Elastic Search. You should take a quick look at these and use the one you feel most confortable with.
If you are using search functionality in your app I suggest using SearchLogic gem
It is easy to use and effective..
SearchLogic
RailsCasts for searchlogic

Rails, gem with functionality in between enum and many to many

i have im my rails app model which has few options (no more than 10 i think).
Something like Product - Category, where product can be part of 1 or many categories.
But i think i have too few categories to engage fully fledged many-to-many construct.
Moreover the list of categroies is predefined and will almost never change.
I think from sql side this could look like string field categories with such content:"Fruits|Vegetables|..."
Maybe someone know preexisting gem for such functionality, or maybe it is no real advantage doing so and i should choose standart many-to-many ?
I checked acts-as-taggable-on plugin, but it is i think fits not very well for this task.
Enum gems like enumerize i think fit just best, but they are allow only single single value to be choosen.
Currently came out with following combination:
This gem:
https://github.com/pboling/flag_shih_tzu
In model:
class Product < ActiveRecord::Base
KINDS = { 1 => :fruit, 2 => :vegetable }
include FlagShihTzu
attr_accessible *KINDS.values
as_flags KINDS
Then in view (haml):
=form_for [#product] do |f|
-Product::KINDS.each do |k, v|
=f.check_box v
=f.label v
UPDATE:
Yet another gem adressing this problem: https://github.com/joelmoss/bitmask_attributes

ActiveAdmin eager loading not working for model named "Search" (name collision)

I've been using ActiveAdmin eager loading in almost all my models. For instance, this works great for my Coach model:
app/admin/coaches.rb
ActiveAdmin.register Coach do
controller do
def scoped_collection
Coach.includes(:addresses, :user, :sport, {:user => :user_metric})
end
end
end
However, when I recently tried this same thing with my Search model (which I use to record searches users have done):
app/admin/searches.rb
ActiveAdmin.register Search do
controller do
def scoped_collection
Search.includes(:sport)
end
end
end
I get the following error when I try to visit /admin/searches
NoMethodError in Admin::SearchesController#index
undefined method `includes' for
ActiveAdmin::ResourceController::Collection::Search:Module
app/admin/searches.rb:5:in `scoped_collection'
I believe what may be happening here is the constant Search I'm using in my eager loading is referring to some internal ActiveAdmin module rather than my ActiveRecord model. Is there a way to prevent this name collision? Maybe ActiveRecord::Search (or something like that)? Or possibly something else entirely is going on here?
The constant Search works everywhere else on the site, and the ActiveAdmin searches page worked fine before trying to implement eager loading.
As #Fivell recommended, try ::Search instead of Search.
It looks like your reference to Search in app/admin/searches.rb:5 is actually referencing ActiveAdmin::ResourceController::Collection::Search.
If that doesn't solve the issue, and it might not, I recommend renaming your Search class to something else, as name collisions tend to crop up weird bugs...
Good luck!

Constructing a has-and-belongs-to-many query

I have a rails app (running on version 2.2.2) that has a model called Product. Product is in a has-and-belongs-to-many relationship with Feature. The problem is that I need have search functionality for the products. So I need to be able to search for products that have a similar name, and some other attributes. The tricky part is that the search must also return products that have the exact set of features indicated in the search form (this is represented by a bunch of checkboxes). The following code works, but it strikes me as rather inefficient:
#products = Product.find(:all, :conditions=>["home=? AND name LIKE ? AND made_by LIKE ? AND supplier LIKE ? AND ins LIKE ?",hme,'%'+opts[0]+'%','%'+opts[1]+'%','%'+opts[3]+'%','%'+opts[4]+'%'])
#see if any of these products have the correct features
if !params[:feature_ids].nil?
f = params[:feature_ids].collect{|i| i.to_i}
#products.delete_if {|x| x.feature_ids!=f}
end
I'm sorry that my grasp of rails/sql is so weak, but does anyone have any suggestions about how to improve the above code? Thanks so much!
First, i would recommend you to manually write a FeatureProduct model (and not use the default 'has_and_belongs_to_many')
EG
class FeatureProduct
belongs_to :feature
belongs_to :product
end
class Product
has_many :feature_products
has_many :features, :through => :feature_products
end
class Feature
has_many :feature_products
has_many :products, :through => :feature_products
end
For the search: You may find the gem SearchLogic to be exactly what you need. It has support for 'LIKE' conditions (it means that you can write in a more 'Rails way' your query). It also has support for performing a search with conditions on a related model (on your Feature model, to be more precise).
The solution would be something like:
search = Product.search
search.name_like = opt[0]
search.made_by_like = opt[1]
...
search.feature_products_id_equals = your_feature_ids
..
#product_list = search.all
There is also an excellent screencast explaining the use of this gem.
Good luck :)