Module: Ditty::Helpers::Component

Includes:
ActiveSupport::Inflector
Defined in:
lib/ditty/helpers/component.rb

Instance Method Summary collapse

Instance Method Details

#apply_filter(ds, filter) ⇒ Object



99
100
101
102
103
104
# File 'lib/ditty/helpers/component.rb', line 99

def apply_filter(ds, filter)
  value = params[filter[:name]].send(filter[:modifier])
  return ds.where(filter[:field] => value) unless filter[:field].to_s.include? '.'

  ds.where(filter_field(filter) => filter_value(filter))
end

#check_countObject

param :count, Integer, min: 1, default: 10 # Can’t do this, since count can be ‘all`



14
15
16
17
18
19
20
21
22
23
# File 'lib/ditty/helpers/component.rb', line 14

def check_count
  return 10 if params[:count].nil?

  count = params[:count].to_i
  return count if count >= 1

  excp = Sinatra::Param::InvalidParameterError.new 'Parameter cannot be less than 1'
  excp.param = :count
  raise excp
end

#datasetObject



25
26
27
28
29
30
# File 'lib/ditty/helpers/component.rb', line 25

def dataset
  ds = policy_scope(settings.model_class)
  ds = ds.where Sequel.|(*search_filters) unless search_filters.blank?
  ds = ds.order ordering unless ordering.blank?
  filtered(ds)
end

#dehumanizedObject



64
65
66
# File 'lib/ditty/helpers/component.rb', line 64

def dehumanized
  settings.dehumanized || underscore(heading)
end

#filter_association(filter) ⇒ Object



118
119
120
121
122
123
124
# File 'lib/ditty/helpers/component.rb', line 118

def filter_association(filter)
  assoc = filter[:field].to_s.split('.').first.to_sym
  assoc = settings.model_class.association_reflection(assoc)
  raise "Unknown association #{assoc}" if assoc.nil?

  assoc
end

#filter_field(filter) ⇒ Object



106
107
108
# File 'lib/ditty/helpers/component.rb', line 106

def filter_field(filter)
  filter[:field].to_s.split('.').first.to_sym
end

#filter_fieldsObject



68
69
70
# File 'lib/ditty/helpers/component.rb', line 68

def filter_fields
  self.class.const_defined?('FILTERS') ? self.class::FILTERS : []
end

#filter_value(filter) ⇒ Object



110
111
112
113
114
115
116
# File 'lib/ditty/helpers/component.rb', line 110

def filter_value(filter)
  field = filter[:field].to_s.split('.').last.to_sym
  assoc = filter_association(filter)
  value = params[filter[:name].to_s].send(filter[:modifier])
  value = assoc.associated_dataset.first(field => value)
  value.nil? ? assoc.associated_class.new : value
end

#filtered(ds) ⇒ Object



76
77
78
79
80
81
# File 'lib/ditty/helpers/component.rb', line 76

def filtered(ds)
  filters.each do |filter|
    ds = apply_filter(ds, filter)
  end
  ds
end

#filtersObject



83
84
85
86
87
88
89
90
91
# File 'lib/ditty/helpers/component.rb', line 83

def filters
  filter_fields.map do |filter|
    next if params[filter[:name]].blank?

    filter[:field] ||= filter[:name]
    filter[:modifier] ||= :to_s # TODO: Do this with Sinatra Param?
    filter
  end.compact
end

#heading(action = nil) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
# File 'lib/ditty/helpers/component.rb', line 52

def heading(action = nil)
  @headings ||= begin
    heading = settings.heading || settings.model_class.to_s.demodulize.singularize.titleize
    h = Hash.new(heading)
    h[:new] = "New #{heading}"
    h[:list] = pluralize heading
    h[:edit] = "Edit #{heading}"
    h
  end
  @headings[action]
end

#listObject



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/ditty/helpers/component.rb', line 32

def list
  param :q, String
  param :page, Integer, min: 1, default: 1
  param :sort, String
  param :order, String, in: %w[asc desc], transform: :downcase
  # TODO: Can we dynamically validate the search / filter fields?

  ds = dataset
  ds = ds.dataset if ds.respond_to?(:dataset)
  params[:order] ||= 'asc' if params[:sort]
  return ds if params[:count] == 'all'

  params[:count] = check_count

  # Account for difference between sequel paginate and will paginate
  return ds.paginate(page: params[:page], per_page: params[:count]) if ds.is_a?(Array)

  ds.paginate(params[:page], params[:count])
end

#orderingObject



93
94
95
96
97
# File 'lib/ditty/helpers/component.rb', line 93

def ordering
  return if params[:sort].blank?

  Sequel.send(params[:order].to_sym, params[:sort].to_sym)
end

#search_filtersObject



126
127
128
129
130
# File 'lib/ditty/helpers/component.rb', line 126

def search_filters
  return [] if params[:q].blank?

  searchable_fields.map { |f| Sequel.ilike(f.to_sym, "%#{params[:q]}%") }
end

#searchable_fieldsObject



72
73
74
# File 'lib/ditty/helpers/component.rb', line 72

def searchable_fields
  self.class.const_defined?('SEARCHABLE') ? self.class::SEARCHABLE : []
end