Class: Xsdk::Scaffold::Rails::BaseDatatable

Inherits:
Object
  • Object
show all
Defined in:
lib/xsdk/scaffold/rails/base_datatable.rb

Instance Method Summary collapse

Constructor Details

#initialize(params, clazz) ⇒ BaseDatatable

Returns a new instance of BaseDatatable.



5
6
7
8
9
10
11
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 5

def initialize(params, clazz)
  @options = JSON.parse(params[:options]).with_indifferent_access
  @clazz = clazz
  @foreign_keys = get_foreign_key_map(clazz)
  @only_schema = @options[:only_schema]
  @default_values = @options.try(:[], :default) || {}
end

Instance Method Details

#as_jsonObject



13
14
15
16
17
18
19
20
21
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 13

def as_json(*)
  return { columns: build_headers } if @only_schema

  {
    rows: paginate(get_data),
    total_rows: get_count,
    columns: build_headers
  }
end

#association_is_has_many_or_one?(v) ⇒ Boolean

Returns:

  • (Boolean)


59
60
61
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 59

def association_is_has_many_or_one?(v)
  v[:association_type] == :has_many || v[:association_type] == :has_one
end

#associationsObject



283
284
285
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 283

def associations
  {}
end

#associations_includeObject



84
85
86
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 84

def associations_include
  associations.select{ |_, v| association_is_has_many_or_one?(v) }.map { |_, v| v[:include] }
end

#build_headersObject

Build columns



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 102

def build_headers
  headers = columns_orderd.map do |c|
    {
      value: c, # warehouse_id
      table_value: get_table_value(c),	# "mag1"
      text: get_text(c),											# "Identificatore"
      type: get_type(c),											# "string"
      in_form: get_in_form(c),	# true/false
      in_table: table_columns.include?(c), # true/false
      table: get_table(c),	# warehouses
      source: get_source(c),	# identifier
      in_form_disabled: disabled_form_columns.include?(c),	# true/false
      min_search_size: get_min_search_size(c),
      enum_cols: get_enum_cols(c),
      subschema: get_subschema(c),
      show_new_record: get_if_can_show_new_record(c),
      entity_name: get_entity_name(c),
      default: get_default_value(c)
    }
  end
  headers << { text: 'Azioni', value: 'actions', type: '', in_form: false, in_table: true }
  headers
end

#column_name_ordered_listObject



181
182
183
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 181

def column_name_ordered_list
  []
end

#columnsObject



189
190
191
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 189

def columns
  @clazz.column_names - %w[created_at updated_at] + transient_columns.keys
end

#columns_orderdObject



185
186
187
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 185

def columns_orderd
  column_name_ordered_list + (columns - column_name_ordered_list)
end

#disabled_form_columnsObject



201
202
203
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 201

def disabled_form_columns
  []
end

#enum_methodsObject



47
48
49
50
51
52
53
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 47

def enum_methods
  enum_methods = []
  @clazz.defined_enums.each do |k, _v|
    enum_methods << "#{k}_text"
  end
  enum_methods
end

#form_columnsObject



197
198
199
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 197

def form_columns
  columns - ['id']
end

#get_countObject



272
273
274
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 272

def get_count
  @clazz.count
end

#get_dataObject



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 63

def get_data
  data = get_raw_data
  associations.reject { |_k, v| association_is_has_many_or_one?(v) }.each do |_, value|
    data = data.send(value[:join_type] || :joins, value[:relation])
  end
  to_select = associations.reject{ |_k, v| association_is_has_many_or_one?(v) }
    .reject { |_k, v| v[:source] == 'id' }
    .map do |key, value|
      table_name = @foreign_keys[key][0][:class_name].constantize.table_name
      "#{table_name}.#{value[:source]} AS #{value[:relation]}_#{value[:source]}"
    end

  data = data.select("#{@clazz.table_name}.*", *to_select)

  associations.select { |_k, v| association_is_has_many_or_one?(v) }.each do |_, v|
    data = data.includes(v[:join]).references(v[:join])
  end

  data
end

#get_default_value(c) ⇒ Object



151
152
153
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 151

def get_default_value(c)
  @default_values[c]
end

#get_entity_name(key) ⇒ Object



93
94
95
96
97
98
99
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 93

def get_entity_name(key)
  key = key.to_sym
  assoc = associations[key]
  return nil if assoc.nil?

  assoc[:relation]
end

#get_enum_cols(c) ⇒ Object



155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 155

def get_enum_cols(c)
  arr = []
  if @clazz.defined_enums.key?(c)
    @clazz.defined_enums[c].each do |k, _v|
      arr << {
        value: k,
        text: @clazz.human_attribute_name("#{c}_enum.#{k}")
      }
    end
  end
  arr
end

#get_foreign_key_map(clazz) ⇒ Object



276
277
278
279
280
281
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 276

def get_foreign_key_map(clazz)
  clazz.reflect_on_all_associations.select { |a| a.macro == :belongs_to }
       .map { |a| { key: a.foreign_key, class_name: a.class_name } }
       .group_by { |a| a[:key] }
       .with_indifferent_access
end

#get_if_can_show_new_record(key) ⇒ Object



88
89
90
91
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 88

def get_if_can_show_new_record(key)
  key = key.to_sym
  (associations.select { |k, v| k == key && v[:show_new_record] }).any?
end

#get_in_form(key) ⇒ Object



126
127
128
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 126

def get_in_form(key)
  (@options[:form_columns] || form_columns).include?(key)
end

#get_min_search_size(c) ⇒ Object



168
169
170
171
172
173
174
175
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 168

def get_min_search_size(c)
  ax = associations.with_indifferent_access
  if ax.key?(c) && ax[c][:source] == 'id'
    ax[c][:min_search_size]
  else
    3
  end
end

#get_raw_dataObject



55
56
57
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 55

def get_raw_data
  @clazz.all
end

#get_source(c) ⇒ Object



220
221
222
223
224
225
226
227
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 220

def get_source(c)
  ax = associations.with_indifferent_access
  if ax.key?(c) && !association_is_has_many_or_one?(ax[c])
    ax[c][:source]
  else
    c
  end
end

#get_subschema(c) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 130

def get_subschema(c)
  subschema = nil
  ax = associations.with_indifferent_access
  if ax.key?(c) && association_is_has_many_or_one?(ax[c])
    child_options = { options: {}.to_json }
    child_options = { options: ax[c][:options].to_json } if ax[c][:options].present?
    begin
      datatable = "#{ax[c][:clazz]}Datatable".constantize
      dt = datatable.new(child_options)
    rescue StandardError
      dt = BaseDatatable.new(child_options, ax[c][:clazz])
    end
    subschema = dt.build_headers
    subschema = subschema.reject { |sc| sc[:type] == 'foreign_key' && sc[:table] == @clazz.table_name }
    subschema << { text: 'Elimina', value: '_destroy', type: '', in_form: false, in_table: false }
    subschema << { text: 'Uuid', value: '_uuid', type: 'uuid', in_form: false, in_table: false }
    subschema.each { |s| s[:is_subschema] = true }
  end
  subschema
end

#get_table(c) ⇒ Object



209
210
211
212
213
214
215
216
217
218
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 209

def get_table(c)
  ax = associations.with_indifferent_access
  if @foreign_keys.key?(c)
    @foreign_keys[c][0][:class_name].constantize.table_name
  elsif ax.key?(c) && association_is_has_many_or_one?(ax[c])
    ax[c][:clazz].table_name
  else
    @clazz.table_name
  end
end

#get_table_value(c) ⇒ Object



259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 259

def get_table_value(c)
  ax = associations.with_indifferent_access
  if ax.key?(c)
    if association_is_has_many_or_one?(ax[c])
      c
    else
      "#{ax[c][:relation]}_#{ax[c][:source]}"
    end
  else
    c
  end
end

#get_text(c) ⇒ Object



229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 229

def get_text(c)
  ax = associations.with_indifferent_access
  if @foreign_keys.key?(c)
    @foreign_keys[c][0][:class_name].constantize.model_name.human.capitalize
  elsif ax.key?(c) && association_is_has_many_or_one?(ax[c])
    ax[c][:clazz].model_name.human.capitalize
  elsif transient_columns.key?(c)
    transient_columns[c][:text]
  else
    @clazz.human_attribute_name(c).capitalize
  end
end

#get_type(c) ⇒ Object



242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 242

def get_type(c)
  ax = associations.with_indifferent_access
  if @foreign_keys.key?(c)
    'foreign_key'
  elsif ax.key?(c) && (ax[c][:association_type] == :has_many)
    'has_many'
  elsif ax.key?(c) && (ax[c][:association_type] == :has_one)
    'has_one'
  elsif @clazz.defined_enums.key?(c)
    'enum'
  elsif transient_columns.key?(c)
    transient_columns[c][:type]
  else
    @clazz.type_for_attribute(c).type
  end
end

#keys_to_excludeObject



43
44
45
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 43

def keys_to_exclude
  []
end

#methodsObject



205
206
207
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 205

def methods
  []
end

#paginate(data) ⇒ Object

Build rows



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 25

def paginate(data)
  per_page = @options[:itemsPerPage]
  page = @options[:page] - 1
  sort = @options[:sortBy]
  direction = @options[:sortDesc]
  order_string = sort.map.with_index { |k, idx| "#{sorting_map[k.to_sym]} #{direction[idx] ? 'DESC' : 'ASC'}" }
  
  if per_page > 0
    data = data.limit(per_page).offset(page * per_page)
  end
  
  data.order(order_string).as_json(
    methods: methods + enum_methods,
    except: keys_to_exclude,
    include: associations_include
  )
end

#sorting_mapObject



287
288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 287

def sorting_map
  build_headers.map do |h|
    if h[:type] == 'foreign_key'
      [h[:table_value].to_sym, "#{h[:table]}.#{h[:source]}"]
    elsif h[:type] == 'enum'
      ["#{h[:value]}_text".to_sym, "#{h[:table]}.#{h[:table_value]}"]
    elsif h[:type].nil? || h[:value] == 'actions'
      [nil]
    else
      [h[:value].to_sym, "#{h[:table]}.#{h[:table_value]}"]
    end
  end.filter { |a| a[0] }.to_h
end

#table_columnsObject



193
194
195
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 193

def table_columns
  columns
end

#transient_columnsObject



177
178
179
# File 'lib/xsdk/scaffold/rails/base_datatable.rb', line 177

def transient_columns
  @options[:transient_columns] || {}
end