Class: Raymond::Control

Inherits:
Object
  • Object
show all
Defined in:
lib/raymond/control.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(controller, sort_params, options = {}) ⇒ Control

Constructor



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/raymond/control.rb', line 17

def initialize(controller, sort_params, options = {})
  @attr, @dir = if sort_params.kind_of?(String)
    (sort_params || '').split('-').map(&:to_sym)
  else
    raise ArgumentError.new("sort_params must be either String or Array.") unless sort_params.kind_of?(Array)
    raise ArgumentError.new("As as Array, sort_params must be in the form of [:my_attribute, :up_or_down].") unless sort_params.size == 2
    sort_params.map(&:to_sym)
  end

  @class = if (klass = options[:class])
    if klass.kind_of?(Class)
      klass
    else
      klass.to_s.constantize    # ActiveSupport dependency
    end
  else
    # class was not explicitly specified; we assume it's related to the name controller name
    controller.class.name[0..-11].singularize.constantize  # 'Controller' is 11 characters long; ActiveSupport dependency!
    #
    # achieve the same without ActiveSupport:
    #@class = Module.const_get(controller.class.name[0..-11].singularize) # 'Controller' is 11 characters long
  end

  # try to use the controllers logger, if available
  @logger = options[:logger] || (controller.respond_to?(:logger) && controller.logger)

  self.logger.warn "Trying to sort by `#{@attr}`, which is not allowed for class #{@class}." unless attr_valid?
end

Instance Attribute Details

#attrObject (readonly)

Returns the value of attribute attr.



5
6
7
# File 'lib/raymond/control.rb', line 5

def attr
  @attr
end

#dirObject (readonly)

Returns the value of attribute dir.



5
6
7
# File 'lib/raymond/control.rb', line 5

def dir
  @dir
end

Instance Method Details

#attr_valid?Boolean



76
77
78
# File 'lib/raymond/control.rb', line 76

def attr_valid?
  @class.sort_attributes.include?(@attr)
end

#current_attr?(attr) ⇒ Boolean



80
81
82
# File 'lib/raymond/control.rb', line 80

def current_attr?(attr)
  attr.to_sym == @attr && self.attr_valid?
end

#inverse_dirObject



72
73
74
# File 'lib/raymond/control.rb', line 72

def inverse_dir
  SORTING_DIRECTIONS.keys.detect{|dir| dir != @dir}
end

#loggerObject

:nodoc:



84
85
86
# File 'lib/raymond/control.rb', line 84

def logger #:nodoc:
  @logger ||= (Module.const_defined?('Rails') && Rails.logger)
end

#resultArray

Returns the sorted result When a block is given, you can hook in between SQL sorting and Ruby sorting.

Example:

@sorting = Raymond::Control.new(self, params[:sort], :class => MyFaboulousModel)
@retrieved_data = @sorting.result do |arel|
  arel.limit(20).offset(120).where(:foo => 'bar')
end


56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/raymond/control.rb', line 56

def result
  result = @class.scoped

  sql_order = @class.sql_sort_order(@attr, @dir)
  result = result.order(sql_order) unless sql_order.blank?

  result = yield(result) if block_given?

  sort_proc = @class.sort_proc(@attr)
  result = result.sort_by{|obj| sort_proc.call(obj)} if sort_proc

  return result.reverse if sort_proc && @dir == :up

  result
end