lib/listings/base.rb in listings-0.0.3 vs lib/listings/base.rb in listings-0.1.0
- old
+ new
@@ -13,10 +13,13 @@
attr_accessor :params
attr_accessor :search_criteria
attr_accessor :search_filters
+ attr_reader :data_source
+ delegate :items, to: :data_source
+
def initialize
@page_size = self.class.page_size
end
def name
@@ -34,11 +37,11 @@
# if it is not filterable, all the search is used as search criteria
self.search_criteria = self.search
self.search_filters = {}
else
# otherwise parse the search stripping out allowed filterable fields
- self.search_filters, self.search_criteria = parse_filter(self.search, self.filters)
+ self.search_filters, self.search_criteria = parse_filter(self.search, self.filters.map(&:key))
end
end
def parse_filter(text, filter_keys)
filters = {}
@@ -61,73 +64,61 @@
end
return text
end
- def filter_items(params, items)
+ def filter_items(params)
+ columns # prepare columns
+ filters # prepare filters
+
self.page = params[param_page] || 1
self.scope = scope_by_name(params[param_scope])
self.search = params[param_search]
parse_search
- items = paginatable(scope.apply(self, items)) unless scope.nil?
+ unless scope.nil?
+ data_source.scope do |items|
+ scope.apply(self, items)
+ end
+ end
if search_criteria.present? && self.searchable?
- criteria = []
- values = []
- self.columns.select(&:searchable?).each do |col|
- criteria << "#{model_class.table_name}.#{col.name} like ?"
- values << "%#{search_criteria}%"
- end
- items = items.where(criteria.join(' or '), *values)
+ search_fields = self.columns.select(&:searchable?).map &:field
+ data_source.search(search_fields, search_criteria)
end
if filterable?
- # pluck filters values before applying filters/pagination/sorting
- self.filter_values = {}
- filters.each do |v|
- self.filter_values[v] = items.pluck("distinct #{v}").reject(&:nil?)
+ filters.each do |filter_view|
+ filter_view.values # prepare values
end
self.search_filters.each do |key, filter_value|
- items = items.where("#{model_class.table_name}.#{key} = ?", filter_value)
+ data_source.filter(filter_with_key(key).field, filter_value)
end
end
if params.include?(param_sort_by)
- sort_col = column_with_name(params[param_sort_by])
+ sort_col = column_with_key(params[param_sort_by])
sort_col.sort = params[param_sort_direction]
- items = items.reorder("#{sort_col.sort_by} #{params[param_sort_direction]}")
+ data_source.sort(sort_col.field, params[param_sort_direction])
end
if paginated?
- items = items.page(page).per(page_size)
+ data_source.paginate(page, page_size)
end
- if items.is_a?(Class)
- items = items.all
- end
-
- items
+ self.items
end
def query_items(params)
@params = params
- items = self.model_class
+ @data_source = Sources::DataSource.for(self.model_class)
@has_active_model_source = items.respond_to? :human_attribute_name
- self.items = filter_items(self.scoped_params, paginatable(items))
+ filter_items(self.scoped_params)
end
- def paginatable(array_or_model)
- if array_or_model.is_a?(Array) && paginated? && !array_or_model.respond_to?(:page)
- Kaminari.paginate_array(array_or_model)
- else
- array_or_model
- end
- end
-
def has_active_model_source?
@has_active_model_source
end
def selectable?
@@ -150,11 +141,19 @@
def value_for(column, item)
column.value_for(self, item)
end
- def column_with_name(name)
- self.columns.find { |c| c.name.to_s == name.to_s }
+ def column_with_key(key)
+ self.columns.find { |c| c.key == key }
+ end
+
+ def filter_with_key(key)
+ self.filters.find { |c| c.key == key }
+ end
+
+ def human_name(field)
+ field.human_name
end
def searchable?
self.columns.any? &:searchable?
end