lib/magic_grid/definition.rb in magic_grid-0.10.4 vs lib/magic_grid/definition.rb in magic_grid-0.11.0
- old
+ new
@@ -1,20 +1,24 @@
-#require 'will_paginate/view_helpers/action_view'
+require 'magic_grid/logger'
+require 'magic_grid/collection'
module MagicGrid
class Definition
- #include WillPaginate::ActionView
- attr_accessor :columns, :collection, :magic_id, :options, :params,
+ attr_reader :columns, :magic_id, :options, :params,
:current_sort_col, :current_order, :default_order, :per_page
+ def collection
+ @collection.collection
+ end
+
DEFAULTS = {
:class => [],
:top_pager => false,
:bottom_pager => true,
:remote => false,
:per_page => 30,
- :searchable => false,
+ :searchable => [],
:search_method => :search,
:min_search_length => 3,
:id => false,
:searcher => false,
:needs_searcher => false,
@@ -54,17 +58,17 @@
raise "I have no idea what that is, but it's not a Hash or an Array"
end
@default_order = @options[:default_order]
@params = controller && controller.params || {}
@per_page = @options[:per_page]
- @collection = collection
+ @collection = Collection[collection, self]
begin
#if @collection.respond_to? :table
table_name = @collection.quoted_table_name
table_columns = @collection.table.columns.map {|c| c.name}
rescue
- Rails.logger.debug "Given collection doesn't respond to :table well"
+ MagicGrid.logger.debug "Given collection doesn't respond to :table well"
table_name = nil
table_columns = @columns.each_index.to_a
end
i = 0
hash = []
@@ -88,110 +92,72 @@
else
@magic_id = hash.join.hash.abs.to_s(36)
@magic_id << @collection.to_sql.hash.abs.to_s(36) if @collection.respond_to? :to_sql
end
@current_sort_col = sort_col_i = param(:col, @options[:default_col]).to_i
- if @collection.respond_to?(:order) and @columns.count > sort_col_i and @columns[sort_col_i].has_key?(:sql)
+ if @collection.sortable? and @columns.count > sort_col_i and @columns[sort_col_i].has_key?(:sql)
sort_col = @columns[sort_col_i][:sql]
@current_order = order(param(:order, @default_order))
sort_dir = order_sql(@current_order)
- @collection = @collection.order("#{sort_col} #{sort_dir}")
+ @collection.apply_sort(sort_col, sort_dir)
else
- Rails.logger.debug "#{self.class.name}: Ignoring sorting on non-AR collection"
+ MagicGrid.logger.debug "#{self.class.name}: Ignoring sorting on non-AR collection"
end
- @options[:searchable] = [] if @options[:searchable] and not @options[:searchable].kind_of? Array
-
- if @collection.respond_to?(:where) or @options[:listener_handler].respond_to?(:call)
+ if @collection.filterable? or @options[:listener_handler].respond_to?(:call)
if @options[:listener_handler].respond_to? :call
- @collection = @options[:listener_handler].call(@collection)
+ @collection.apply_filter_callback @options[:listener_handler]
else
@options[:listeners].each_pair do |key, value|
if @params[value] and not @params[value].to_s.empty?
- @collection = @collection.where(value => @params[value])
+ @collection.apply_filter(value => @params[value])
end
end
end
else
unless @options[:listeners].empty?
- Rails.logger.warn "#{self.class.name}: Ignoring listener on dumb collection"
+ MagicGrid.logger.warn "#{self.class.name}: Ignoring listener on dumb collection"
@options[:listeners] = {}
end
end
+
+ @options[:searchable] = Array(@options[:searchable])
@options[:current_search] ||= param(:q)
- if (@collection.respond_to?(:where) or
- (@options[:search_method] and @collection.respond_to?(@options[:search_method])))
- if param(:q) and not param(:q).empty? and @options[:searchable]
- orig_collection = @collection
- begin
- @collection = @collection.__send__(@options[:search_method], param(:q))
- rescue
- Rails.logger.debug "Given collection doesn't respond to #{@options[:search_method]} well"
- @collection = orig_collection
- search_cols = @options[:searchable].map do |searchable|
- case searchable
- when Symbol
- known = @columns.find {|col| col[:col] == searchable}
- if known and known.key?(:sql)
- known[:sql]
- else
- "#{table_name}.#{@collection.connection.quote_column_name(searchable.to_s)}"
- end
- when Integer
- @columns[searchable][:sql]
- when String
- searchable
- else
- raise "Searchable must be identifiable"
- end
- end
- unless search_cols.empty?
- begin
- clauses = search_cols.map {|c| c << " LIKE :search" }.join(" OR ")
- @collection = @collection.where(clauses, {:search => "%#{param(:q)}%"})
- rescue
- Rails.logger.debug "Given collection doesn't respond to :where well"
- @collection = orig_collection
- end
- end
- end
+ if @collection.searchable?
+ if param(:q) and not param(:q).empty? and not @options[:searchable].empty?
+ @collection.apply_search(param(:q))
end
else
- if @options[:searchable] or param(:q)
- Rails.logger.warn "#{self.class.name}: Ignoring searchable fields on non-AR collection"
+ if not @options[:searchable].empty? or param(:q)
+ MagicGrid.logger.warn "#{self.class.name}: Ignoring searchable fields on non-AR collection"
end
- @options[:searchable] = false
+ @options[:searchable] = []
end
- if not @options[:searcher] and @options[:searchable]
- @options[:needs_searcher] = true
- @options[:searcher] = param_key(:searcher)
- end
+
# Do collection filter first, may convert from AR to Array
- if @options[:collection_post_filter?] and @collection.respond_to?(:post_filter)
- @collection = @collection.post_filter(controller)
+ if @options[:collection_post_filter?] and @collection.has_post_filter?
+ @collection.apply_post_filter
end
if @options[:post_filter] and @options[:post_filter].respond_to?(:call)
- @collection = @options[:post_filter].call(@collection)
+ @collection.apply_filter_callback @options[:post_filter]
end
# Paginate at the very end, after all sorting, filtering, etc..
- if @per_page
- if @collection.respond_to? :paginate
- @collection = @collection.paginate(:page => current_page,
- :per_page => @per_page)
- elsif @collection.respond_to? :page
- @collection = @collection.page(current_page).per(@per_page)
- elsif @collection.is_a?(Array) and Module.const_defined?(:Kaminari)
- @collection = Kaminari.paginate_array(@collection).page(current_page).per(@per_page)
- else
- original = @collection
- @collection = @collection.to_enum.each_slice(@per_page).drop(current_page - 1).first.to_a
- class << @collection
- attr_accessor :current_page, :total_pages, :original_count
- end
- @collection.current_page = current_page
- @collection.original_count = original.count
- @collection.total_pages = original.count / @per_page
- end
+ @collection.apply_pagination(current_page, @per_page)
+ end
+
+ def searchable?
+ @collection.searchable? and not @options[:searchable].empty?
+ end
+
+ def needs_searcher?
+ @options[:needs_searcher] or (searchable? and not @options[:searcher])
+ end
+
+ def searcher
+ if needs_searcher?
+ param_key(:searcher)
+ else
+ @options[:searcher]
end
end
def param_key(key)
"#{@magic_id}_#{key}".to_sym