Module: FiltersControllerAddOn::ClassMethods

Defined in:
lib/spyro/filters_controller_add_on.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.execute_order(value, scope, keys, args, desc) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/spyro/filters_controller_add_on.rb', line 115

def self.execute_order value, scope, keys, args, desc
  value = keys.first unless keys.include? value.to_sym

  my_scope = args.find {|arg| arg.is_a?(Hash) and arg[value.to_sym]}
  scope = if my_scope
    scope.instance_exec &(my_scope[value.to_sym])
  else
    scope.order(value.to_sym)
  end

  if desc
    scope = (scope.respond_to?(:desc) ? scope.desc : scope.reverse_order)
  end
  scope = execute_order(keys.first, scope, keys, args, ordered_options[:default] == :desc) unless value.to_sym == keys.first.to_sym

  return scope
end

Instance Method Details

#filtered(*args) ⇒ Object

filter=campus:Cluj;



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/spyro/filters_controller_add_on.rb', line 82

def filtered *args #filter=campus:Cluj;
  cattr_accessor :filtered_keys
  cattr_accessor :filtered_values
  cattr_accessor :filtered_args

  args = args.map {|arg| arg.is_a?(Hash) ? arg.to_a[0] : [arg, nil]}.to_h
  self.filtered_keys = args.keys
  self.filtered_values = self.filtered_keys.map {|k| [k, (args[k] ? args[k][1].call : resource_class.pluck(k).uniq)] }.to_h
  self.filtered_args = args

  has_scope :filter, :only => [:index] do |controller, scope, values|
    values.split(";").each do |value|
      name, filter = *value.split(':', 2)
      if name.to_sym.in? args.keys
        scopes = args[name.to_sym]
        if scopes
          scope = scope.instance_exec(filter.split(','), &(scopes[0]))
        else
          scope = scope.where(name => filter.split(','))
        end
      end
    end

    scope
  end
end

#ordered(*args) ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/spyro/filters_controller_add_on.rb', line 110

def ordered *args
  cattr_accessor :ordered_keys
  cattr_accessor :ordered_options

  self.ordered_options = (args.count > 1 ? args.extract_options! : {})
  def self.execute_order value, scope, keys, args, desc
    value = keys.first unless keys.include? value.to_sym

    my_scope = args.find {|arg| arg.is_a?(Hash) and arg[value.to_sym]}
    scope = if my_scope
      scope.instance_exec &(my_scope[value.to_sym])
    else
      scope.order(value.to_sym)
    end

    if desc
      scope = (scope.respond_to?(:desc) ? scope.desc : scope.reverse_order)
    end
    scope = execute_order(keys.first, scope, keys, args, ordered_options[:default] == :desc) unless value.to_sym == keys.first.to_sym

    return scope
  end

  args = [*args].flatten
  keys = args.flat_map {|arg| arg.is_a?(Hash) ? arg.map(&:first) : arg}.map(&:to_sym)
  self.ordered_keys = keys

  raise "Missing params" if keys.empty? or (keys.length == 1 and keys.first.to_sym == :default)
  raise "Bad value for default" if self.ordered_options and !self.ordered_options[:default].in? [nil, :desc]

  has_scope :order, :default => keys.first.to_s, :only => [:index], as: :sort do |controller, scope, value|
    if !controller.params[:sort].blank? or controller.params[:rev_sort].blank?
      execute_order(value, scope, keys, args, false).send((controller.params[:sort].nil? and self.ordered_options[:default] == :desc) ? :desc : :all)
    else
      scope.all
    end
  end

  has_scope :rev_order, :default => keys.first.to_s, :only => [:index], as: :rev_sort do |controller, scope, value|
    if !controller.params[:rev_sort].blank? and controller.params[:sort].blank?
      execute_order(value, scope, keys, args, true)
    else
      scope.all
    end
  end
end

#paginateObject



12
13
14
# File 'lib/spyro/filters_controller_add_on.rb', line 12

def paginate
  has_scope :page, :default => 1, :only => [:index], :if => lambda {|c| (c.params[:format].try(:to_sym) || :html).in? [:html, :js] }
end

#paginatedObject



16
17
18
# File 'lib/spyro/filters_controller_add_on.rb', line 16

def paginated
  paginate
end

#ranged(*args) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/spyro/filters_controller_add_on.rb', line 53

def ranged *args
  cattr_accessor :ranged_keys
  cattr_accessor :ranged_values
  cattr_accessor :ranged_args

  args = args.map {|arg| arg.is_a?(Hash) ? arg.to_a[0] : [arg, nil]}.to_h
  self.ranged_keys = args.keys
  self.ranged_values = self.ranged_keys.map {|k| [k, (args[k] ? args[k][2].call : resource_class.min_max(k))] }.to_h
  self.ranged_args = args

  has_scope :range, :only => [:index] do |controller, scope, values| #http://localhost:3000/exams?range=created_at:2015-06-03%2000:00%3bmax_people:50,100&sort=name
    values.split(";").each do |value|
      name, min, max = *value.match(/(\w+):([^,]+)?,?([^,]+)?/).values_at(1, 2, 3)
      if name.to_sym.in? args.keys
        scopes = args[name.to_sym]
        if scopes
          scope = scope.instance_exec(min, &(scopes[0])) if min
          scope = scope.instance_exec(max, &(scopes[1])) if max
        else
          scope = scope.where("#{resource_class.table_name}.#{name} >= ?", min) if min
          scope = scope.where("#{resource_class.table_name}.#{name} <= ?", max) if max
        end
      end
    end

    scope
  end
end

#searched(*args) ⇒ Object

in:name CPP in:campus a



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/spyro/filters_controller_add_on.rb', line 21

def searched *args # recode moi avec `or` avec Rails 5 :'(
  cattr_accessor :searched_keys
  cattr_accessor :searched_args

  self.searched_keys = args.map {|arg| (arg.is_a?(Hash) ? arg.to_a[0].first : arg)}
  self.searched_args = args

  has_scope :search, :only => [:index] do |controller, scope, values|
    sql = values.reverse.split(/\s+(?!\S+:\S+)/).map(&:reverse).reverse.map do |value| # feinte du variable-length look behind
      in_search, value = value.match(/(in:(?<filter>\S+)\s+)?(?<search>.+)/).values_at 1, 2

      sql = args.map do |arg|
        key = (arg.is_a?(Hash) ? arg.to_a[0].first : arg)
        next if !in_search.nil? and in_search != key.to_s

        if arg.is_a? Hash
          scope.instance_exec(value, &(arg.to_a[0].last)).to_sql
        else
          scope.where("#{resource_class.table_name}.#{arg} ilike ?", "%#{value}%").to_sql
        end
      end.reject(&:blank?)

      sql = (sql.any? ? sql.join(' UNION ') : scope.where("1=0").to_sql)
      resource_class.from("(#{sql}) #{resource_class.table_name}").to_sql
    end

    sql = (sql.any? ? sql.join(' INTERSECT ') : scope.where("1=0").to_sql)

    resource_class.from("(#{sql}) #{resource_class.table_name}")
  end
end