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