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.



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

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

Instance Attribute Details

#paramsObject (readonly)

Returns the value of attribute params.



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

def params
  @params
end

Class Method Details

.generate(*args) ⇒ Object



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

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
12
# File 'lib/buscar/index.rb', line 7

def each
	collection = paginate? ? records_on_page(page) : records
	collection.each do |record|
		yield record
	end
end

#empty?Boolean

Returns:

  • (Boolean)


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

def empty?
	records.empty?
end

#filter_paramObject

Returns one of the following in descending order of preference:

  • params

  • default_filter_option

  • ‘none’



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

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

#filter_param_optionsObject



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

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

#generate!Object



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
70
# File 'lib/buscar/index.rb', line 40

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



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

def length
	records.length
end

#optional_params(*keys) ⇒ Object



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

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.



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

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

#page_countObject



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

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

#recordsObject



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

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.



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

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’



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

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

#sort_param_optionsObject



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

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