class MagicGrid::Collection

Constants

DEFAULTS

Attributes

current_page[R]
options[W]
original_count[R]
per_page[R]
searchable_columns[RW]
searches[R]
total_pages[R]

Public Class Methods

create_or_reuse(collection, opts = {}) click to toggle source
# File lib/magic_grid/collection.rb, line 49
def self.create_or_reuse(collection, opts = {})
  if collection.is_a?(self)
    collection.options = opts
    collection
  else
    Collection.new(collection, opts)
  end
end
new(collection, opts = {}) click to toggle source
# File lib/magic_grid/collection.rb, line 18
def initialize(collection, opts = {})
  @collection = collection || []
  @options = opts
  @current_page = 1
  @sorts = []
  @filter_callbacks = []
  @filters = []
  @searches = []
  @post_filters = []
  @post_filter_callbacks = []
  @paginations = []
  @searchable_columns = []
  @@kaminari_class = defined?(Kaminari) ? Kaminari : nil
end

Public Instance Methods

add_post_filter_callback(callback) click to toggle source
# File lib/magic_grid/collection.rb, line 152
def add_post_filter_callback(callback)
  if callback.respond_to? :call
    @reduced_collection = nil
    @post_filter_callbacks << callback
  end
end
apply_all_operations(collection) click to toggle source
# File lib/magic_grid/collection.rb, line 227
def apply_all_operations(collection)
  @sorts.each do |ordering|
    collection = collection.order(ordering)
  end
  if @filter_callbacks.empty?
    @filters.each do |hsh|
      collection = collection.where(hsh)
    end
  else
    @filter_callbacks.each do |callback|
      collection = callback.call(collection)
    end
  end
  @searches.each do |query|
    collection = perform_search(collection, query)
  end
  # Do collection filter first, may convert from AR to Array
  @post_filters.each do |filter|
    collection = collection.__send__(filter)
  end
  @post_filter_callbacks.each do |callback|
    collection = callback.call(collection)
  end
  # Paginate at the very end, after all sorting, filtering, etc..
  perform_pagination(collection)
end
apply_filter(filters = {}) click to toggle source
# File lib/magic_grid/collection.rb, line 138
def apply_filter(filters = {})
  if filterable? and not filters.empty?
    @reduced_collection = nil
    @filters << filters
  end
end
apply_filter_callback(callback) click to toggle source
# File lib/magic_grid/collection.rb, line 145
def apply_filter_callback(callback)
  if callback.respond_to? :call
    @reduced_collection = nil
    @filter_callbacks << callback
  end
end
apply_pagination(current_page) click to toggle source
# File lib/magic_grid/collection.rb, line 189
def apply_pagination(current_page)
  @current_page = current_page
  @reduced_collection = nil
end
apply_sort(col, dir) click to toggle source
# File lib/magic_grid/collection.rb, line 103
def apply_sort(col, dir)
  if sortable? and col.sortable?
    @reduced_collection = nil
    @sorts << "#{col.custom_sql} #{dir}"
  end
end
bound_current_page(page, per_page, total_entries) click to toggle source
# File lib/magic_grid/collection.rb, line 268
def bound_current_page(page, per_page, total_entries)
  pages = calculate_total_pages(per_page, total_entries)
  if page < 1
    1
  elsif page > pages
    pages
  else
    page
  end
end
calculate_total_pages(per_page, total_entries) click to toggle source
# File lib/magic_grid/collection.rb, line 258
def calculate_total_pages(per_page, total_entries)
  pages = total_entries / per_page
  pages += 1 if total_entries % per_page > 0
  if pages < 1
    1
  else
    pages
  end
end
collection() click to toggle source
# File lib/magic_grid/collection.rb, line 254
def collection
  @reduced_collection ||= apply_all_operations(@collection)
end
column_names() click to toggle source
# File lib/magic_grid/collection.rb, line 58
def column_names
  @collection.table.columns.map{|c| c[:name]}
rescue
  MagicGrid.logger.debug("Given collection doesn't respond to #table well: #{$!}")
  []
end
count(collection = nil) click to toggle source
# File lib/magic_grid/collection.rb, line 171
def count(collection = nil)
  count_or_hash = collection || @collection
  while count_or_hash.respond_to? :count
    count_or_hash = count_or_hash.send :count, *(Array([count_options]).compact)
  end
  count_or_hash
end
count_options() click to toggle source
# File lib/magic_grid/collection.rb, line 45
def count_options
  options[:count]
end
default_paginate(collection, page, per_page) click to toggle source
# File lib/magic_grid/collection.rb, line 194
def default_paginate(collection, page, per_page)
  collection = collection.to_enum
  collection = collection.each_slice(@per_page)
  collection = collection.drop(@current_page - 1)
  collection = collection.first.to_a
  class << collection
    attr_accessor :current_page, :total_pages, :original_count
  end
  collection
end
enable_post_filter(yes = true) click to toggle source
# File lib/magic_grid/collection.rb, line 163
def enable_post_filter(yes = true)
  @reduced_collection = nil
  if yes and has_post_filter?
    @post_filters << :post_filter
  end
  self
end
filterable?() click to toggle source
# File lib/magic_grid/collection.rb, line 134
def filterable?
  @collection.respond_to? :where
end
has_post_filter?() click to toggle source
# File lib/magic_grid/collection.rb, line 159
def has_post_filter?
  @collection.respond_to? :post_filter
end
hash_string() click to toggle source
# File lib/magic_grid/collection.rb, line 73
def hash_string
  if @collection.respond_to? :to_sql
    @collection.to_sql.hash.abs.to_s(36)
  else
    options.hash.abs.to_s(36)
  end
end
options() click to toggle source
# File lib/magic_grid/collection.rb, line 41
def options
  DEFAULTS.merge(@options || {})
end
per_page=(n) click to toggle source
# File lib/magic_grid/collection.rb, line 179
def per_page=(n)
  @original_count = self.count @collection
  @per_page = n
  if @per_page
    @total_pages = calculate_total_pages(@per_page, @original_count)
  else
    @total_pages = 1
  end
end
perform_pagination(collection) click to toggle source
# File lib/magic_grid/collection.rb, line 205
def perform_pagination(collection)
  return collection unless @per_page

  total_entries = count(collection)
  @current_page = bound_current_page(@current_page,
                                     @per_page,
                                     total_entries)

  if collection.respond_to? :paginate
    collection.paginate(:page => @current_page,
                        :per_page => @per_page,
                        :total_entries => total_entries)
  elsif collection.respond_to? :page
    collection.page(@current_page).per(@per_page)
  elsif collection.is_a?(Array) and @@kaminari_class
     @@kaminari_class.paginate_array(collection).
                      page(@current_page).per(@per_page)
  else
     default_paginate(collection, @current_page, @per_page)
  end
end
quote_column_name(col) click to toggle source
# File lib/magic_grid/collection.rb, line 65
def quote_column_name(col)
  if col.is_a? Symbol and @collection.respond_to? :quoted_table_name
    "#{quoted_table_name}.#{@collection.connection.quote_column_name(col.to_s)}"
  else
    col.to_s
  end
end
search_using_builtin(collection, q) click to toggle source
# File lib/magic_grid/collection.rb, line 81
def search_using_builtin(collection, q)
  collection.__send__(options[:search_method], q)
end
search_using_where(collection, q) click to toggle source
# File lib/magic_grid/collection.rb, line 85
def search_using_where(collection, q)
  result = collection
  unless searchable_columns.empty?
    begin
      search_cols = searchable_columns.map {|c| c.custom_sql || c.name }
      clauses = search_cols.map {|c| c << " LIKE :search" }.join(" OR ")
      result = collection.where(clauses, {:search => "%#{q}%"})
    rescue
      MagicGrid.logger.debug "Given collection doesn't respond to :where well"
    end
  end
  result
end
searchable?() click to toggle source
# File lib/magic_grid/collection.rb, line 110
def searchable?
  (filterable? and not searchable_columns.empty?) or
    (options[:search_method] and
     @collection.respond_to? options[:search_method])
end
sortable?() click to toggle source
# File lib/magic_grid/collection.rb, line 99
def sortable?
  @collection.respond_to?(:order)
end