lib/query_helper.rb in query_helper-0.2.7 vs lib/query_helper.rb in query_helper-0.2.8

- old
+ new

@@ -27,11 +27,13 @@ single_record: false, # whether or not you expect the record to return a single result, if toggled, only the first result will be returned associations: [], # a list of activerecord associations you'd like included in the payload as_json_options: nil, # a list of as_json options you'd like run before returning the payload custom_mappings: {}, # custom keyword => sql_expression mappings api_payload: false, # Return the paginated payload or simply return the result array - preload: [] # preload activerecord associations - used instead of `associations` when you don't want them included in the payload + preload: [], # preload activerecord associations - used instead of `associations` when you don't want them included in the payload + search_fields: [], + search_string: nil ) @query = query.class < ActiveRecord::Relation ? query.to_sql : query @model = query.class < ActiveRecord::Relation ? query.base_class : model @bind_variables = bind_variables @sql_filter = sql_filter @@ -42,10 +44,12 @@ @associations = associations @as_json_options = as_json_options @custom_mappings = custom_mappings @api_payload = api_payload @preload = preload + @search_fields = search_fields + @search_string = search_string if @page && @per_page # Determine limit and offset limit = @per_page offset = (@page - 1) * @per_page @@ -62,21 +66,23 @@ filters: [], associations: [], as_json_options: nil, single_record: nil, custom_mappings: nil, - preload: [] + preload: [], + search_fields: nil ) @query = query.class < ActiveRecord::Relation ? query.to_sql : query if query @model = query.class < ActiveRecord::Relation ? query.base_class : model if model || query @bind_variables.merge!(bind_variables) filters.each{ |f| add_filter(**f) } @associations = @associations | associations @single_record = single_record if single_record @as_json_options = as_json_options if as_json_options @custom_mappings = custom_mappings if custom_mappings @preload = preload if preload + @search_fields = search_fields if search_fields return self end def add_filter(operator_code:, criterion:, comparate:) @sql_filter.filter_values["comparate"] = { operator_code => criterion } @@ -100,18 +106,31 @@ @sql_sort.column_maps = column_maps # create the filters from the column maps @sql_filter.create_filters() + having_clauses = @sql_filter.having_clauses + where_clauses = @sql_filter.where_clauses + + if @search_string + search_filter = search_filter(column_maps) + if search_filter[:placement] == :where + where_clauses << search_filter[:filter] + else + having_clauses << search_filter[:filter] + end + end + + # merge the filter bind variables into the query bind variables @bind_variables.merge!(@sql_filter.bind_variables) # Execute Sql Query manipulator = SqlManipulator.new( sql: @query, - where_clauses: @sql_filter.where_clauses, - having_clauses: @sql_filter.having_clauses, + where_clauses: where_clauses, + having_clauses: having_clauses, order_by_clauses: @sql_sort.parse_sort_string, include_limit_clause: @page && @per_page ? true : false, additional_select_clauses: @sql_sort.select_strings ) manipulator.build() @@ -228,6 +247,22 @@ query: @query, custom_mappings: @custom_mappings, model: @model ) end + + def search_filter(column_maps) + raise ArgumentError.new("search_fields not defined") unless @search_fields.length > 0 + placement = :where + maps = column_maps.select do |cm| + placement = :having if cm.aggregate + @search_fields.include? cm.alias_name + end + bind_variable = ('a'..'z').to_a.shuffle[0,20].join.to_sym + @bind_variables[bind_variable] = "%#{@search_string}%" + filter = "#{maps.map{|m| "#{m.sql_expression}::varchar"}.join(" || ")} ilike :#{bind_variable}" + return { + filter: filter, + placement: placement + } + end end