Skip to content

Instantly share code, notes, and snippets.

@codeodor
Created June 3, 2011 21:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save codeodor/1007199 to your computer and use it in GitHub Desktop.
Save codeodor/1007199 to your computer and use it in GitHub Desktop.
Beginnings of filter_query_param hook for modifying where clauses before the query in ActiveRecord
ActiveRecord::QueryMethods.class_eval do
# this is code from the original file, with the .map do |x| ... added to build_where
# ideally, we would alias original_where where and work with the relation.where_values, but
# I haven't yet been successful in that attempt.
def where(opts, *rest)
return self if opts.blank?
relation = clone
relation.where_values +=
build_where(opts, rest) # begin the added code (next line)
.map do |condition| # is this a valid solution to the shared @@query_filters problem?
ActiveRecord::Base.query_filters.select{|qf| qf[:table_name] == table.name }.each do |query_filter|
# I'm not really sure what we're trying to do here. Should we drop the
# requirement to pass the param name to the filter_query_param method and just
# send the whole condition to the filter_method?
#
# If not, what are we sending as input to the filter_method?
condition.gsub!(/\b#{query_filter[:param]}\b/, query_filter[:filter_method].call(query_filter[:param]))
end
condition
end
# end the added code
relation
end
end
ActiveRecord::Base.class_eval do
# this means all our models are sharing the same @@query_filters. That won't work.
@@query_filters = []
def self.query_filters
@@query_filters
end
def self.filter_query_param(param, filter_method_name) # we can figure out the &block later
@@query_filters << {:param=>param, :filter_method=>method(filter_method_name), :table_name=>self.table_name}
# is this a valid solution to the shared @@query_filters problem?
end
end
class Blah < ActiveRecord::Base
# I don't like having to call filter_query_param after defining the filter_methods
# But if we wait until later to turn it into a method, it's not defined.
# How can we work around that?
def self.lower(match)
"lower(#{match})"
end
filter_query_param(:title, :lower)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment