I'm using active_admin and that's bringing in meta_search to my project. (Which I don't want to use for anything else).
It seems to be defining the search method on all my models, which then means when I include tire, I can't use it's search method.
There seems to be something strange with how it's defining the method also - method_defined? says that the search method is not defined, yet when I call it I get the meta_search one. Even if I define my own search method in the class, when I call Document.search I still get meta_search.
EDIT: I'd be interested in general ways of dealing with this sort of thing - I have solved this particular issue by using Model.tire.search (since tire is also accessible that way), but I still hate that a gem I'm not even using can force me to use a workaround in the rest of my project.
EDIT: I don't know of a good way of including code blocks in answers to answers, so I'll put this here.
# Meta_search loaded, tire is not
1.9.3p125 :001 > require "tire" #=> true
1.9.3p125 :002 > Document.send(:include, Tire::Model::Search)
=> Document(...)
1.9.3p125 :003 > Document.search
Document Load (2.1ms) SELECT "documents".* FROM "documents"
# I get meta_search, as I should
# Tire loaded (and the include Tire::Model::Search is inside the class definition), meta_search is not loaded
1.9.3p125 :001 > Document.search
# I get tire, as I should
1.9.3p125 :002 > require "meta_search" #=> true
1.9.3p125 :003 > Document.search
# I still get tire, all is well
# Tire loaded, meta_search is not loaded
1.9.3p125 :001 > require "meta_search" #=> true
1.9.3p125 :002 > Document.search
Document Load (1.8ms) SELECT "documents".* FROM "documents"
# I get meta_search, even though Document.search was already defined!
# Tire loaded, meta_search is not loaded, RAILS_ENV="production"
Loading production environment (Rails 3.2.2)
1.9.3p125 :001 > require "meta_search"
=> true
1.9.3p125 :002 > Document.search
# I get tire!
My interpretation of this is that there is a bug with how meta_search detects if search is already defined when the class hasn't actually loaded. Hooray!
the relevant 2 lines:
https://github.com/ernie/meta_search/blob/master/lib/meta_search.rb#L55
https://github.com/ernie/meta_search/blob/master/lib/meta_search/searches/active_record.rb#L46
I don't think it is a bug, it is just how things are.
in scenario 3 In development environment, you do not preload the model. When you require 'meta_search', it will define 'search' on
ActiveRecord::Base
. Then you sayDocument
, which loads the model, will first inherit defined search method so when it includes Tire search module, it will leave search aliased to metasearch.In production mode (scenario 4) as well as scenario 2, you preload the document model before metasearch so Tire will define search. Now requiring metasearch will only have effect on newly loaded classes.
You can see that the order in which gems are defined does not count. But you can undefine search method after gem require.
so any time later we load a model class and include tire, search will correctly go to tire, both in development and production.
This is not ideal since the search method for non-tire models will not delegate to metasearch, in fact it will not be defined. So probably the second solution is best: here you overwrite the search method with one which checks for tire at runtime:
does this help?