Skip to content

Commit 9655407

Browse files
committed
Add a meta search mock
Currently raises if a search is passed, is there just for debugging purposes.
1 parent d0db736 commit 9655407

File tree

2 files changed

+233
-0
lines changed

2 files changed

+233
-0
lines changed

lib/active_admin/mongoid/document.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
require 'meta_search/searches/mongoid'
2+
13
module ActiveAdmin::Mongoid::Document
24
extend ActiveSupport::Concern
35

lib/meta_search/searches/mongoid.rb

Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
require 'active_support/concern'
2+
require 'meta_search/method'
3+
require 'meta_search/builder'
4+
5+
module MetaSearch
6+
module Searches
7+
8+
module Mongoid
9+
extend ActiveSupport::Concern
10+
11+
def method_missing? name, *args, &block
12+
if name =~ metasearch_regexp
13+
field_name, condition = $1, $2
14+
raise [field_name, condition].inspect
15+
else
16+
super
17+
end
18+
end
19+
20+
def respond_to? name, include_private = false
21+
name =~ metasearch_regexp or super
22+
end
23+
24+
module ClassMethods
25+
def metasearch(params = nil, options = nil)
26+
options ||= {}
27+
params ||= {}
28+
raise [options, params] unless [options, params].all?(&:empty?)
29+
scoped
30+
end
31+
end
32+
33+
def metasearch_regexp
34+
@metasearch_regexp ||= begin
35+
field_names = fields.map(&:last).map(&:name)
36+
37+
# general_conditions = %w[eq]
38+
# string_conditions = %w[starts_with ends_with contains]
39+
# id_conditions = []
40+
# checkbox_conditions = %w[in]
41+
# range_conditions = %w[gte lte]
42+
# number_conditions = %w[numeric]
43+
# boolean_conditions = %w[is_true is_false is_present is_blank is_null is_not_null]
44+
45+
conditions = MetaSearch::DEFAULT_WHERES.map {|condition| condition[0...-1]} # pop tail options
46+
47+
/\A(#{field_names.join('|')})_(#{conditions.join('|')})/
48+
end
49+
end
50+
end
51+
52+
# module Mongoid
53+
#
54+
# def self.included(base)
55+
# base.extend ClassMethods
56+
#
57+
# base.class_eval do
58+
# class_attribute :_metasearch_include_attributes, :_metasearch_exclude_attributes
59+
# class_attribute :_metasearch_include_associations, :_metasearch_exclude_associations
60+
# class_attribute :_metasearch_methods
61+
# self._metasearch_include_attributes =
62+
# self._metasearch_exclude_attributes =
63+
# self._metasearch_exclude_associations =
64+
# self._metasearch_include_associations = {}
65+
# self._metasearch_methods = {}
66+
# end
67+
# end
68+
#
69+
# module ClassMethods
70+
# # Prepares the search to run against your model. Returns an instance of
71+
# # MetaSearch::Builder, which behaves pretty much like an ActiveRecord::Relation,
72+
# # in that it doesn't actually query the database until you do something that
73+
# # requires it to do so.
74+
# #
75+
# # Options:
76+
# #
77+
# # * +params+ - a hash of valid searches with keys that are valid according to
78+
# # the docs in MetaSearch::Where.
79+
# # * +opts+ - A hash of additional information that will be passed through to
80+
# # the search's Builder object. +search_key+, if present, will override the
81+
# # default param name, 'search', in any sort_links generated by this Builder.
82+
# # All other keys are passed untouched to the builder, and available from the
83+
# # Builder's +options+ reader for use in :if blocks supplied to attr_searchable
84+
# # and friends.
85+
# def metasearch(params = nil, opts = nil)
86+
# builder = Searches.for(self).new(self, opts || {})
87+
# builder.build(params || {})
88+
# end
89+
#
90+
# alias_method :search, :metasearch unless respond_to?(:search)
91+
#
92+
# def _metasearch_method_authorized?(name, metasearch_object)
93+
# name = name.to_s
94+
# meth = self._metasearch_methods[name]
95+
# meth && (meth[:if] ? meth[:if].call(metasearch_object) : true)
96+
# end
97+
#
98+
# def _metasearch_attribute_authorized?(name, metasearch_object)
99+
# name = name.to_s
100+
# if self._metasearch_include_attributes.empty?
101+
# !_metasearch_excludes_attribute?(name, metasearch_object)
102+
# else
103+
# _metasearch_includes_attribute?(name, metasearch_object)
104+
# end
105+
# end
106+
#
107+
# def _metasearch_association_authorized?(name, metasearch_object)
108+
# name = name.to_s
109+
# if self._metasearch_include_associations.empty?
110+
# !_metasearch_excludes_association?(name, metasearch_object)
111+
# else
112+
# _metasearch_includes_association?(name, metasearch_object)
113+
# end
114+
# end
115+
#
116+
# private
117+
#
118+
# # Excludes model attributes from searchability. This means that searches can't be created against
119+
# # these columns, whether the search is based on this model, or the model's attributes are being
120+
# # searched by association from another model. If a Comment <tt>belongs_to :article</tt> but declares
121+
# # <tt>attr_unsearchable :user_id</tt> then <tt>Comment.search</tt> won't accept parameters
122+
# # like <tt>:user_id_equals</tt>, nor will an Article.search accept the parameter
123+
# # <tt>:comments_user_id_equals</tt>.
124+
# def attr_unsearchable(*args)
125+
# if table_exists?
126+
# opts = args.extract_options!
127+
# args.flatten.each do |attr|
128+
# attr = attr.to_s
129+
# raise(ArgumentError, "No persisted attribute (column) named #{attr} in #{self}") unless self.columns_hash.has_key?(attr)
130+
# self._metasearch_exclude_attributes = self._metasearch_exclude_attributes.merge(
131+
# attr => {
132+
# :if => opts[:if]
133+
# }
134+
# )
135+
# end
136+
# end
137+
# end
138+
#
139+
# # Like <tt>attr_unsearchable</tt>, but operates as a whitelist rather than blacklist. If both
140+
# # <tt>attr_searchable</tt> and <tt>attr_unsearchable</tt> are present, the latter
141+
# # is ignored.
142+
# def attr_searchable(*args)
143+
# if table_exists?
144+
# opts = args.extract_options!
145+
# args.flatten.each do |attr|
146+
# attr = attr.to_s
147+
# raise(ArgumentError, "No persisted attribute (column) named #{attr} in #{self}") unless self.columns_hash.has_key?(attr)
148+
# self._metasearch_include_attributes = self._metasearch_include_attributes.merge(
149+
# attr => {
150+
# :if => opts[:if]
151+
# }
152+
# )
153+
# end
154+
# end
155+
# end
156+
#
157+
# # Excludes model associations from searchability. This mean that searches can't be created against
158+
# # these associations. An article that <tt>has_many :comments</tt> but excludes comments from
159+
# # searching by declaring <tt>assoc_unsearchable :comments</tt> won't make any of the
160+
# # <tt>comments_*</tt> methods available.
161+
# def assoc_unsearchable(*args)
162+
# opts = args.extract_options!
163+
# args.flatten.each do |assoc|
164+
# assoc = assoc.to_s
165+
# raise(ArgumentError, "No such association #{assoc} in #{self}") unless self.reflect_on_all_associations.map {|a| a.name.to_s}.include?(assoc)
166+
# self._metasearch_exclude_associations = self._metasearch_exclude_associations.merge(
167+
# assoc => {
168+
# :if => opts[:if]
169+
# }
170+
# )
171+
# end
172+
# end
173+
#
174+
# # As with <tt>attr_searchable</tt> this is the whitelist version of
175+
# # <tt>assoc_unsearchable</tt>
176+
# def assoc_searchable(*args)
177+
# opts = args.extract_options!
178+
# args.flatten.each do |assoc|
179+
# assoc = assoc.to_s
180+
# raise(ArgumentError, "No such association #{assoc} in #{self}") unless self.reflect_on_all_associations.map {|a| a.name.to_s}.include?(assoc)
181+
# self._metasearch_include_associations = self._metasearch_include_associations.merge(
182+
# assoc => {
183+
# :if => opts[:if]
184+
# }
185+
# )
186+
# end
187+
# end
188+
#
189+
# def search_methods(*args)
190+
# opts = args.extract_options!
191+
# authorizer = opts.delete(:if)
192+
# args.flatten.map(&:to_s).each do |arg|
193+
# self._metasearch_methods = self._metasearch_methods.merge(
194+
# arg => {
195+
# :method => MetaSearch::Method.new(arg, opts),
196+
# :if => authorizer
197+
# }
198+
# )
199+
# end
200+
# end
201+
#
202+
# alias_method :search_method, :search_methods
203+
#
204+
# def _metasearch_includes_attribute?(name, metasearch_object)
205+
# attr = self._metasearch_include_attributes[name]
206+
# attr && (attr[:if] ? attr[:if].call(metasearch_object) : true)
207+
# end
208+
#
209+
# def _metasearch_excludes_attribute?(name, metasearch_object)
210+
# attr = self._metasearch_exclude_attributes[name]
211+
# attr && (attr[:if] ? attr[:if].call(metasearch_object) : true)
212+
# end
213+
#
214+
# def _metasearch_includes_association?(name, metasearch_object)
215+
# assoc = self._metasearch_include_associations[name]
216+
# assoc && (assoc[:if] ? assoc[:if].call(metasearch_object) : true)
217+
# end
218+
#
219+
# def _metasearch_excludes_association?(name, metasearch_object)
220+
# assoc = self._metasearch_exclude_associations[name]
221+
# assoc && (assoc[:if] ? assoc[:if].call(metasearch_object) : true)
222+
# end
223+
#
224+
# end
225+
# end
226+
#
227+
# def self.for(klass)
228+
# DISPATCH[klass.name]
229+
# end
230+
end
231+
end

0 commit comments

Comments
 (0)