Class: Buscar::Index

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/buscar/index.rb

Defined Under Namespace

Classes: Chain

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(params = {}) ⇒ Index

Returns a new instance of Index.



71
72
73
# File 'lib/buscar/index.rb', line 71

def initialize(params = {})
	@params = params
end

Instance Attribute Details

#paramsObject (readonly)

Returns the value of attribute params.



100
101
102
# File 'lib/buscar/index.rb', line 100

def params
  @params
end

Class Method Details

.generate(*args) ⇒ Object



33
34
35
36
37
# File 'lib/buscar/index.rb', line 33

def self.generate(*args)
	index = new(*args)
	index.generate!
	index
end

Instance Method Details

#eachObject

Views can call this method to iterate over the current page’s records. Uses the value returned by #page, which in turn uses the value of @params



7
8
9
10
11
# File 'lib/buscar/index.rb', line 7

def each
	records_on_page(page).each do |record|
		yield record
	end
end

#empty?Boolean

Returns:

  • (Boolean)


13
14
15
# File 'lib/buscar/index.rb', line 13

def empty?
	@records.empty?
end

#filter_paramObject

Returns one of the following in descending order of preference:

  • params

  • default_filter_option

  • ‘none’



21
22
23
# File 'lib/buscar/index.rb', line 21

def filter_param
	@params[:filter] || (respond_to?(:default_filter_option, true) ? default_filter_option : 'none')
end

#filter_param_optionsObject



25
26
27
28
29
30
31
# File 'lib/buscar/index.rb', line 25

def filter_param_options
	filter_options.collect do |opt|
		arr = [opt[0]]
		arr << opt[2] if opt.length == 3
		arr
	end
end

#generate!Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/buscar/index.rb', line 39

def generate!
	unless respond_to?(:finder, true)
		raise 'Subclasses of Index must define #finder, which must return something that responds to #find. For example, #finder may return an ActiveRecord::Base subclass.'
	end
	
	raise "Buscar::Index#conditions is deprecated. Name your method where_clause instead." if respond_to?(:conditions, true)
	raise "Buscar::Index#order is deprecated. Name your method order_clause instead." if respond_to?(:order, true)
	raise "Buscar::Index#include_clause is deprecated. Name your method includes_clause instead." if respond_to?(:include, true)
	
	@records = finder.scoped # Get the bare relation object in case none of the modifiers are used
	# Use each AR query modifier other than #where and #order if applicable
	%w(having select group limit offset joins includes lock readonly from).each do |meth|
		@records = @records.send(meth, send("#{meth}_clause".to_sym)) if respond_to?("#{meth}_clause".to_sym, true)
	end
	
	chained_filters = filter
	chained_filters = chain(chained_filters) unless chained_filters.is_a?(Chain) # filter might return a Chain or a single filtering rule. If it's a single one, we'll put it in an array.
	@filter_procs = chained_filters.select { |f| f.is_a?(Proc) } # Procs will be triggered by the first call to #records so as not to defeat lazy loading
	where_filters = chained_filters.select { |f| !f.is_a?(Proc) } # SQL filters can be used right away
	where_filters.each do |filt|
		@records = @records.where(filt)
	end
	
	sort_rule = sort
	# If sorting by a proc, do it on the first call to #records so as not to defeat lazy loading 
	if sort_rule.is_a?(Proc)
		@sort_proc = sort_rule
	else
		@records = @records.order(sort_rule)
	end
end

#lengthObject



75
76
77
# File 'lib/buscar/index.rb', line 75

def length
	@records.length
end

#optional_params(*keys) ⇒ Object



79
80
81
82
83
84
85
86
# File 'lib/buscar/index.rb', line 79

def optional_params(*keys)
	keys.inject({}) do |hash, key|
		unless @params[key].blank?
			hash[key] = @params[key]
		end
		hash
	end
end

#pageObject

The current page, as determined by @params. Since we want the user to see the page array as one-based, but we use zero-based indices internally, we subtract one from the page number.

Thus, the return value is a zero-based offset.



92
93
94
# File 'lib/buscar/index.rb', line 92

def page
	(@params[:page] || @params['page'] || 1).to_i - 1
end

#page_countObject



96
97
98
# File 'lib/buscar/index.rb', line 96

def page_count
	(@records.length.to_f / records_per_page).ceil
end

#recordsObject



127
128
129
130
131
132
133
134
135
136
# File 'lib/buscar/index.rb', line 127

def records
	unless @procs_called
		@filter_procs.each do |proc|
			@records = @records.select(&proc)
		end
		@records = @records.sort_by(&@sort_proc) if @sort_proc
		@procs_called = true
	end
	@records
end

#records_on_page(page_num) ⇒ Object

page_num is zero-based for this method.



103
104
105
106
107
108
109
# File 'lib/buscar/index.rb', line 103

def records_on_page(page_num)
	if paginate?
		@records.slice((page_num) * records_per_page, records_per_page)
	else
		@records
	end
end

#sort_paramObject

Returns one of the following in descending order of preference:

  • params

  • default_sort_option

  • ‘none’



115
116
117
# File 'lib/buscar/index.rb', line 115

def sort_param
	@params[:sort] || (respond_to?(:default_sort_option, true) ? default_sort_option : 'none')
end

#sort_param_optionsObject



119
120
121
122
123
124
125
# File 'lib/buscar/index.rb', line 119

def sort_param_options
	sort_options.collect do |opt|
		arr = [opt[0]]
		arr << opt[2] if opt.length == 3
		arr
	end
end