class Rokaki::FilterModel::NestedLikeFilters
Attributes
db[R]
filter_key_object[R]
filter_methods[RW]
filter_names[RW]
filter_queries[R]
i_like_semantics[R]
infix[R]
join_key_paths[RW]
key_paths[RW]
like_semantics[R]
method_names[RW]
mode[R]
modes[RW]
names[RW]
or_key[R]
prefix[R]
search_modes[RW]
templates[RW]
type[R]
Public Class Methods
new(filter_key_object:, prefix:, infix:, db:, mode: :and, or_key: :or, type: :like)
click to toggle source
# File lib/rokaki/filter_model/nested_like_filters.rb, line 7 def initialize(filter_key_object:, prefix:, infix:, db:, mode: :and, or_key: :or, type: :like) @filter_key_object = filter_key_object @prefix = prefix @infix = infix @db = db @mode = mode @or_key = or_key @type = type @names = [] @filter_methods = [] @templates = [] @filter_queries = [] @method_names = [] @filter_names = [] @join_key_paths = [] @key_paths = [] @search_modes = [] @modes = [] end
Public Instance Methods
build_filters_data()
click to toggle source
# File lib/rokaki/filter_model/nested_like_filters.rb, line 36 def build_filters_data results = filter_key_object.key_paths.each do |key_path| if key_path.is_a?(Symbol) build_filter_data(key_path) else if key_path.include? or_key build_filter_data(key_path.dup, mode: or_key) else build_filter_data(key_path.dup) end end end end
call()
click to toggle source
# File lib/rokaki/filter_model/nested_like_filters.rb, line 31 def call build_filters_data compound_filters end
compound_filters()
click to toggle source
# File lib/rokaki/filter_model/nested_like_filters.rb, line 50 def compound_filters # key_paths represents a structure like # [ # [ # this is an or # [:articles, :title], # [:articles, :authors, :first_name], # [:articles, :authors, :reviews, :title], # [:articles, :authors, :reviews, :content] # ], # [:articles, :content] # this is an and # ] # # Each item in the array represents a compounded filter # key_paths.each_with_index do |key_path_item, index| base_names = get_name(index) join_map = JoinMap.new(join_key_paths[index]) join_map.call if key_path_item.first.is_a?(Array) item_search_modes = search_modes[index] base_name = base_names.shift method_name = prefix.to_s + ([:filter].push base_name).compact.join(infix.to_s) method_name += (infix.to_s+'or'+infix.to_s) + (base_names).join(infix.to_s+'or'+infix.to_s) item_filter_names = [prefix.to_s + base_name] base_names.each do |filter_base_name| item_filter_names << (prefix.to_s + filter_base_name) end base_modes = modes[index] key_path_item.each_with_index do |key_path, kp_index| build_query(keys: key_path.dup, join_map: join_map.result, mode: base_modes[kp_index], filter_name: item_filter_names[kp_index], search_mode: item_search_modes[kp_index]) end item_filter_queries = filter_queries[index] first_query = item_filter_queries.shift ored = item_filter_queries.map do |query| ".or(#{query})" end filter_conditions = item_filter_names.join(' || ') @filter_methods << "def #{method_name}; #{first_query + ored.join}; end;" @templates << "@model = #{method_name} if #{filter_conditions};" else base_name = get_name(index) filter_name = "#{prefix}#{get_filter_name(index)}" method_name = ([prefix, :filter, base_name]).compact.join(infix.to_s) build_query(keys: key_path_item.dup, join_map: join_map.result, filter_name: filter_name, search_mode: search_modes[index]) @filter_methods << "def #{method_name}; #{filter_queries[index]}; end;" @templates << "@model = #{method_name} if #{filter_name};" end end end
Private Instance Methods
build_filter_data(key_path, mode: :and)
click to toggle source
# File lib/rokaki/filter_model/nested_like_filters.rb, line 131 def build_filter_data(key_path, mode: :and) # if key_path.is_a?(Symbol) # search_mode = @filter_key_object.args[key_path] # name = key_path # filter_name = (prefix.to_s + key_path.to_s) # @names << name # @filter_names << filter_name # @key_paths << key_path # @search_modes << search_mode # @modes << mode # else search_mode = find_mode_key(key_path) key_path.delete(mode) name = key_path.join(infix.to_s) filter_name = key_path.compact.join(infix.to_s) if mode == or_key @names << [@names.pop, name].flatten @filter_names << [@filter_names.pop, filter_name].flatten or_key_paths = @key_paths.pop if or_key_paths.first.is_a?(Array) @key_paths << [*or_key_paths] + [key_path.dup] else @key_paths << [or_key_paths] + [key_path.dup] end @search_modes << [@search_modes.pop, search_mode].flatten @modes << [@modes.pop, mode].flatten else @names << name @filter_names << filter_name @key_paths << key_path.dup # having this wrapped in an array is messy for single items @search_modes << search_mode @modes << mode end join_key_path = key_path.dup leaf = join_key_path.pop if mode == or_key or_join_key_paths = @join_key_paths.pop if or_join_key_paths.first.is_a?(Array) @join_key_paths << [*or_join_key_paths] + [join_key_path.dup] else @join_key_paths << [or_join_key_paths] + [join_key_path.dup] end else if join_key_path.length == 1 @join_key_paths << join_key_path else @join_key_paths << [join_key_path.dup] end end # end end
build_like_query(type:, query:, filter:, search_mode:, key:, leaf:)
click to toggle source
# File lib/rokaki/filter_model/nested_like_filters.rb, line 223 def build_like_query(type:, query:, filter:, search_mode:, key:, leaf:) key_leaf = key ? "#{key.to_s.pluralize}.#{leaf}" : leaf if db == :postgres query = "where(\"#{key_leaf} #{type.to_s.upcase} ANY (ARRAY[?])\", " query += "prepare_terms(#{filter}, :#{search_mode}))" else query = "where(\"#{key_leaf} #{type.to_s.upcase} :query\", " query += "query: \"%\#{#{filter}}%\")" if search_mode == :circumfix query += "query: \"%\#{#{filter}}\")" if search_mode == :prefix query += "query: \"\#{#{filter}}%\")" if search_mode == :suffix end query end
build_query(keys: , join_map:, mode: :and, filter_name:, search_mode:)
click to toggle source
DOUBLE SPLAT HASHES TO MAKE ARG LISTS!
# File lib/rokaki/filter_model/nested_like_filters.rb, line 193 def build_query(keys: , join_map:, mode: :and, filter_name:, search_mode:) leaf = nil leaf = keys.pop query = build_like_query( type: type, query: '', filter: filter_name, search_mode: search_mode, key: keys.last, leaf: leaf ) if join_map.empty? filter_query = "@model.#{query}" elsif join_map.is_a?(Array) filter_query = "@model.joins(*#{join_map}).#{query}" else filter_query = "@model.joins(**#{join_map}).#{query}" end if mode == or_key @filter_queries << [@filter_queries.pop, filter_query].flatten else @filter_queries << filter_query end filter_query end
find_mode_key(keys)
click to toggle source
# File lib/rokaki/filter_model/nested_like_filters.rb, line 123 def find_mode_key(keys) current_like_key = @filter_key_object.args.dup keys.each do |key| current_like_key = current_like_key[key] end current_like_key end
get_filter_name(index)
click to toggle source
# File lib/rokaki/filter_model/nested_like_filters.rb, line 119 def get_filter_name(index) filter_names[index] end
get_name(index)
click to toggle source
# File lib/rokaki/filter_model/nested_like_filters.rb, line 115 def get_name(index) names[index] end