marty 3.1.0 → 4.0.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -7
  3. data/.rubocop.yml +0 -1
  4. data/.rubocop_todo.yml +15 -2
  5. data/Dockerfile.dummy +0 -3
  6. data/Gemfile +15 -21
  7. data/Gemfile.lock +289 -0
  8. data/app/components/marty/data_grid_view.rb +18 -68
  9. data/app/components/marty/extras/layout.rb +1 -1
  10. data/app/components/marty/grid.rb +1 -1
  11. data/app/components/marty/import_view.rb +3 -3
  12. data/app/components/marty/main_auth_app.rb +1 -11
  13. data/app/components/marty/report_form.rb +6 -6
  14. data/app/components/marty/script_form.rb +5 -5
  15. data/app/components/marty/script_tester.rb +2 -2
  16. data/app/components/marty/user_view.rb +9 -3
  17. data/app/models/marty/data_grid.rb +11 -16
  18. data/app/models/marty/event.rb +2 -2
  19. data/app/models/marty/promise.rb +4 -4
  20. data/app/models/marty/role_type.rb +1 -14
  21. data/app/services/marty/data_grid_view/save_grid.rb +2 -2
  22. data/app/services/marty/promises/delorean/create.rb +2 -2
  23. data/app/services/marty/promises/ruby/create.rb +2 -2
  24. data/config/locales/en.yml +2 -11
  25. data/docker-compose.dummy.yml +0 -1
  26. data/lib/marty/content_handler.rb +2 -2
  27. data/lib/marty/data_change.rb +1 -1
  28. data/lib/marty/data_conversion.rb +4 -3
  29. data/lib/marty/data_importer.rb +4 -4
  30. data/lib/marty/mcfly_model.rb +10 -7
  31. data/lib/marty/migrations.rb +1 -1
  32. data/lib/marty/monkey.rb +2 -2
  33. data/lib/marty/promise_job.rb +5 -5
  34. data/lib/marty/promise_proxy.rb +2 -2
  35. data/lib/marty/promise_ruby_job.rb +4 -4
  36. data/lib/marty/version.rb +1 -1
  37. data/marty.gemspec +18 -13
  38. data/other/marty/diagnostic/aws/ec2_instance.rb +2 -17
  39. data/other/marty/diagnostic/database.rb +2 -2
  40. data/other/marty/diagnostic/delayed_job_version.rb +1 -0
  41. data/spec/dummy/app/models/gemini/fannie_bup.rb +20 -13
  42. data/spec/dummy/config/application.rb +0 -1
  43. data/spec/dummy/config/initializers/secret_token.rb +1 -1
  44. data/spec/features/data_grid_spec.rb +46 -109
  45. data/spec/features/reporting_spec.rb +4 -4
  46. data/spec/features/rule_spec.rb +1 -1
  47. data/spec/features/scripting_spec.rb +3 -3
  48. data/spec/features/user_view_spec.rb +8 -17
  49. data/spec/lib/data_importer_spec.rb +8 -8
  50. data/spec/lib/mcfly_model_spec.rb +6 -6
  51. data/spec/models/data_grid_spec.rb +4 -19
  52. data/spec/spec_helper.rb +2 -2
  53. data/spec/support/netzke.rb +3 -4
  54. metadata +53 -50
  55. data/.ssh-docker/.keep +0 -0
  56. data/app/components/marty/data_grid_user_view.rb +0 -39
  57. data/db/migrate/108_add_data_grid_perms.rb +0 -16
  58. data/other/marty/diagnostic/aws/error.rb +0 -8
@@ -115,7 +115,7 @@ module Layout
115
115
  end
116
116
 
117
117
  def get_sorter(col)
118
- lambda { |rel, dir| rel.order(Arel.sql("#{col}::text #{dir}")) }
118
+ lambda { |rel, dir| rel.order("#{col}::text #{dir.to_s}") }
119
119
  end
120
120
 
121
121
  ######################################################################
@@ -52,7 +52,7 @@ class Marty::Grid < ::Netzke::Grid::Base
52
52
 
53
53
  def get_json_sorter(json_col, field)
54
54
  lambda do |r, dir|
55
- r.order(Arel.sql("#{json_col} ->> '#{field}' " + dir.to_s))
55
+ r.order("#{json_col} ->> '#{field}' " + dir.to_s)
56
56
  end
57
57
  end
58
58
 
@@ -84,10 +84,10 @@ class Marty::ImportView < Marty::Form
84
84
  result << messages if messages
85
85
 
86
86
  client.set_result result.join('<br/>')
87
- rescue Marty::DataImporter::Error => e
87
+ rescue Marty::DataImporter::Error => exc
88
88
  result = [
89
- "Import failed on line(s): #{e.lines.join(', ')}",
90
- "Error: #{e.to_s}",
89
+ "Import failed on line(s): #{exc.lines.join(', ')}",
90
+ "Error: #{exc.to_s}",
91
91
  ]
92
92
 
93
93
  client.set_result '<font color="red">' + result.join('<br/>') + '</font>'
@@ -4,7 +4,6 @@ require 'marty/api_log_view'
4
4
  require 'marty/config_view'
5
5
  require 'marty/data_grid_view'
6
6
  require 'marty/schedule_jobs_dashboard'
7
- require 'marty/data_grid_user_view'
8
7
  require 'marty/event_view'
9
8
  require 'marty/import_type_view'
10
9
  require 'marty/new_posting_window'
@@ -97,7 +96,6 @@ class Marty::MainAuthApp < Marty::AuthApp
97
96
  icon_cls: 'fa fa-window-restore glyph',
98
97
  menu: [
99
98
  :data_grid_view,
100
- :data_grid_user_view,
101
99
  :reporting,
102
100
  :scripting,
103
101
  :promise_view,
@@ -239,14 +237,7 @@ class Marty::MainAuthApp < Marty::AuthApp
239
237
  end
240
238
 
241
239
  action :data_grid_view do |a|
242
- a.text = I18n.t('data_grid_view')
243
- a.handler = :netzke_load_component_by_action
244
- a.icon_cls = 'fa fa-table glyph'
245
- a.disabled = !self.class.has_any_perm?
246
- end
247
-
248
- action :data_grid_user_view do |a|
249
- a.text = I18n.t('data_grid_user_view')
240
+ a.text = I18n.t('data_grid_view', default: 'Data Grids')
250
241
  a.handler = :netzke_load_component_by_action
251
242
  a.icon_cls = 'fa fa-table glyph'
252
243
  a.disabled = !self.class.has_any_perm?
@@ -397,7 +388,6 @@ class Marty::MainAuthApp < Marty::AuthApp
397
388
  component :config_view
398
389
 
399
390
  component :data_grid_view
400
- component :data_grid_user_view
401
391
 
402
392
  component :event_view
403
393
 
@@ -61,10 +61,10 @@ class Marty::ReportForm < Marty::Form
61
61
 
62
62
  begin
63
63
  engine.evaluate(node, 'result', d_params)
64
- rescue StandardError => e
65
- Marty::Util.logger.error "run_eval failed: #{e.backtrace}"
64
+ rescue StandardError => exc
65
+ Marty::Util.logger.error "run_eval failed: #{exc.backtrace}"
66
66
 
67
- res = Delorean::Engine.grok_runtime_exception(e)
67
+ res = Delorean::Engine.grok_runtime_exception(exc)
68
68
  res['backtrace'] =
69
69
  res['backtrace'].map { |m, line, fn| "#{m}:#{line} #{fn}" }.join('\n')
70
70
  res
@@ -156,15 +156,15 @@ class Marty::ReportForm < Marty::Form
156
156
  raise 'bad form items' unless items.is_a?(Array)
157
157
  raise 'bad format' unless
158
158
  Marty::ContentHandler::GEN_FORMATS.member?(format)
159
- rescue StandardError => e
159
+ rescue StandardError => exc
160
160
  c.title = 'ERROR'
161
161
  c.items =
162
162
  [
163
163
  {
164
- field_label: 'exception',
164
+ field_label: 'Exception',
165
165
  xtype: :displayfield,
166
166
  name: 'displayfield1',
167
- value: "<span style=\"color:red;\">#{e}</span>"
167
+ value: "<span style=\"color:red;\">#{exc}</span>"
168
168
  },
169
169
  ]
170
170
  return
@@ -83,10 +83,10 @@ class Marty::ScriptForm < Marty::Form
83
83
  begin
84
84
  dev = Marty::Tag.find_by_name('DEV')
85
85
  Marty::ScriptSet.new(dev).parse_check(script.name, data['body'])
86
- rescue Delorean::ParseError => e
87
- client.netzke_notify e.message
86
+ rescue Delorean::ParseError => exc
87
+ client.netzke_notify exc.message
88
88
  client.netzke_apply_form_errors({})
89
- client.set_line_error(e.line)
89
+ client.set_line_error(exc.line)
90
90
  return
91
91
  end
92
92
 
@@ -120,8 +120,8 @@ class Marty::ScriptForm < Marty::Form
120
120
  'PrettyScript',
121
121
  rep_params)
122
122
  client.get_report(path)
123
- rescue StandardError => e
124
- return client.netzke_notify "ERROR: #{e}"
123
+ rescue StandardError => exc
124
+ return client.netzke_notify "ERROR: #{exc}"
125
125
  end
126
126
  end
127
127
 
@@ -75,8 +75,8 @@ class Marty::ScriptTester < Marty::Form
75
75
  client.set_result result.join('<br/>')
76
76
  rescue SystemStackError
77
77
  return client.netzke_notify 'System Stack Error'
78
- rescue StandardError => e
79
- res = Delorean::Engine.grok_runtime_exception(e)
78
+ rescue StandardError => exc
79
+ res = Delorean::Engine.grok_runtime_exception(exc)
80
80
 
81
81
  result = ["Error: #{res['error']}", 'Backtrace:'] +
82
82
  res['backtrace'].map { |m, line, fn| "#{m}:#{line} #{fn}" }
@@ -33,7 +33,9 @@ module Marty; class UserView < Marty::Grid
33
33
  def self.set_roles(roles, user)
34
34
  roles = [] unless roles.present?
35
35
 
36
- roles = ::Marty::RoleType.from_nice_names(roles)
36
+ roles = Marty::RoleType.get_all.select do |role|
37
+ roles.include?(I18n.t("roles.#{role}", default: role))
38
+ end
37
39
 
38
40
  roles_in_user = user.user_roles.map(&:role)
39
41
  roles_to_delete = roles_in_user - roles
@@ -150,10 +152,14 @@ module Marty; class UserView < Marty::Grid
150
152
  c.type = :string
151
153
 
152
154
  c.getter = lambda do |r|
153
- Marty::RoleType.to_nice_names(r.user_roles.map(&:role))
155
+ r.user_roles.map do |ur|
156
+ I18n.t("roles.#{ur.role}", default: ur.role)
157
+ end
154
158
  end
155
159
 
156
- store = ::Marty::RoleType.to_nice_names(::Marty::RoleType::VALUES.sort)
160
+ store = ::Marty::RoleType.get_all.sort.map do |role|
161
+ I18n.t("roles.#{role}", default: role)
162
+ end
157
163
 
158
164
  c.editor_config = {
159
165
  multi_select: true,
@@ -253,7 +253,8 @@ class Marty::DataGrid < Marty::Base
253
253
 
254
254
  # private method used to cache lookup_grid_distinct_entry_h result
255
255
  delorean_fn :lookup_grid_h_priv,
256
- private: true, cache: true, sig: 4 do |pt, dgh, h, distinct|
256
+ to_hash: false, private: true, cache: true, sig: 4 do |pt, dgh, h, distinct|
257
+
257
258
  lookup_grid_distinct_entry_h(
258
259
  pt, h, dgh, nil, true, false, distinct)['result']
259
260
  end
@@ -270,9 +271,9 @@ class Marty::DataGrid < Marty::Base
270
271
  end
271
272
 
272
273
  def self.lookup_grid_distinct_entry_h(
273
- pt, h, dgh, visited = nil, follow = true,
274
- return_grid_data = false, distinct = true
275
- )
274
+ pt, h, dgh, visited = nil, follow = true,
275
+ return_grid_data = false, distinct = true
276
+ )
276
277
 
277
278
  # Perform grid lookup, if result is another data_grid, and follow is true,
278
279
  # then perform lookup on the resulting grid. Allows grids to be nested
@@ -359,19 +360,13 @@ class Marty::DataGrid < Marty::Base
359
360
  def export_array
360
361
  # add data type metadata row if not default
361
362
  lenstr = 'lenient' if lenient
363
+ typestr = data_type unless [nil, DEFAULT_DATA_TYPE].member?(data_type) &&
364
+ !constraint.present?
365
+
366
+ len_dt = [lenstr, typestr].compact.join(' ')
362
367
 
363
- typestr = data_type unless [nil, DEFAULT_DATA_TYPE].member?(data_type)
364
- len_type = [lenstr, typestr].compact.join(' ')
365
-
366
- meta_rows = if (lenient || typestr) && constraint
367
- [[len_type, constraint]]
368
- elsif lenient || typestr
369
- [[len_type]]
370
- elsif constraint
371
- [['', constraint]]
372
- else
373
- []
374
- end
368
+ meta_rows = len_dt.present? || constraint.present? ?
369
+ [[len_dt, constraint]] : []
375
370
 
376
371
  meta_rows += metadata.map do |inf|
377
372
  [inf['attr'], inf['type'], inf['dir'], inf['rs_keep'] || '']
@@ -311,7 +311,7 @@ SQL
311
311
 
312
312
  def self.cleanup
313
313
  where('start_dt < ?', Time.zone.now - 48.hours).delete_all
314
- rescue StandardError => e
315
- Marty::Util.logger.error("event GC error: #{e}")
314
+ rescue StandardError => exc
315
+ Marty::Util.logger.error("event GC error: #{exc}")
316
316
  end
317
317
  end
@@ -132,9 +132,9 @@ class Marty::Promise < Marty::Base
132
132
  # log "OFF0 #{Process.pid} #{last}"
133
133
  begin
134
134
  work_off_job(job)
135
- rescue StandardError => e
135
+ rescue StandardError => exc
136
136
  # log "OFFERR #{exc}"
137
- error = exception_to_result(e)
137
+ error = exception_to_result(exc)
138
138
  last.set_result(error)
139
139
  end
140
140
  # log "OFF1 #{Process.pid} #{last}"
@@ -215,8 +215,8 @@ class Marty::Promise < Marty::Base
215
215
  'start_dt < ? AND parent_id IS NULL',
216
216
  DateTime.now - (all ? 0.hours : 4.hours)
217
217
  ).destroy_all
218
- rescue StandardError => e
219
- Marty::Util.logger.error("promise GC error: #{e}")
218
+ rescue StandardError => exc
219
+ Marty::Util.logger.error("promise GC error: #{exc}")
220
220
  end
221
221
 
222
222
  def exception_to_result(promise:, exception:)
@@ -5,19 +5,6 @@ class Marty::RoleType < Marty::Base
5
5
  'admin',
6
6
  'user_manager',
7
7
  'dev',
8
- 'viewer',
9
- 'data_grid_editor'
8
+ 'viewer'
10
9
  ]
11
-
12
- def self.from_nice_names(roles)
13
- Marty::RoleType.get_all.select do |role|
14
- roles.include?(I18n.t("roles.#{role}", default: role))
15
- end
16
- end
17
-
18
- def self.to_nice_names(roles)
19
- roles.map do |role|
20
- I18n.t("roles.#{role}", default: role)
21
- end
22
- end
23
10
  end
@@ -15,9 +15,8 @@ module Marty
15
15
  end
16
16
 
17
17
  def self.call(params)
18
+ user_perm = Marty::DataGridView.get_edit_save_permission
18
19
  rec_id = params['record_id']
19
- dg = Marty::DataGrid.mcfly_pt('infinity').find_by(group_id: rec_id)
20
- user_perm = Marty::DataGridView.get_edit_permission(dg.permissions)
21
20
  data = params['data']
22
21
  raise GridError.new('entered with view permissions', data, rec_id) if
23
22
  user_perm == 'view'
@@ -25,6 +24,7 @@ module Marty
25
24
  data_as_array = data.map do |row|
26
25
  row.keys.map { |key| row[key] }
27
26
  end
27
+ dg = Marty::DataGrid.mcfly_pt('infinity').find_by(group_id: rec_id)
28
28
  vcnt = dg.metadata.select { |md| md['dir'] == 'v' }.count
29
29
  hcnt = dg.metadata.select { |md| md['dir'] == 'h' }.count
30
30
  cur_data_dim = [dg.data.length, dg.data[0].length]
@@ -31,9 +31,9 @@ module Marty
31
31
  )
32
32
 
33
33
  job = Delayed::Job.enqueue(promise_job)
34
- rescue StandardError => e
34
+ rescue StandardError => exc
35
35
  # log "CALLERR #{exc}"
36
- res = ::Delorean::Engine.grok_runtime_exception(e)
36
+ res = ::Delorean::Engine.grok_runtime_exception(exc)
37
37
  promise.set_start
38
38
  promise.set_result(res)
39
39
  # log "CALLERRSET #{res}"
@@ -29,8 +29,8 @@ module Marty
29
29
  )
30
30
 
31
31
  job = Delayed::Job.enqueue(promise_job)
32
- rescue StandardError => e
33
- res = { 'error' => e.message }
32
+ rescue StandardError => exc
33
+ res = { 'error' => exc.message }
34
34
  promise.set_start
35
35
  promise.set_result(res)
36
36
  raise
@@ -18,10 +18,8 @@ en:
18
18
  create_posting: Create
19
19
  api_auth: API Authorization
20
20
  event_view: Event View
21
- data_grid_view: Data Grids Admin
22
- data_grid: Data Grids Admin
23
- data_grid_user: Data Grids
24
- data_grid_user_view: Data Grids
21
+ data_grid_view: Data Grids
22
+ data_grid: Data Grids
25
23
 
26
24
  data_import_view:
27
25
  import: Import
@@ -32,7 +30,6 @@ en:
32
30
  admin: Admin
33
31
  dev: Developer
34
32
  user_manager: User Manager
35
- data_grid_editor: Data Grid Editor
36
33
 
37
34
  posting_types:
38
35
  BASE: BASE
@@ -179,9 +176,3 @@ en:
179
176
  grid:
180
177
  base:
181
178
  view_record: "%{model} (Read-only)"
182
-
183
- data_grid_view_perms:
184
- perm_view: Can View
185
- perm_edit_data: Can Edit Data
186
- perm_edit_all: Can Edit All
187
-
@@ -24,7 +24,6 @@ services:
24
24
  - .:/opt/app:delegated
25
25
  - '.bash_history.docker:/root/.bash_history'
26
26
  - '.pry_history.docker:/root/.pry_history'
27
- - '.ssh-docker:/root/.ssh'
28
27
  - bundle_box:/bundle_box
29
28
  tty: true
30
29
  stdin_open: true
@@ -34,9 +34,9 @@ module Marty::ContentHandler
34
34
  else
35
35
  res, format = { error: "Unknown format: #{format}" }.to_json, 'json'
36
36
  end
37
- rescue StandardError => e
37
+ rescue StandardError => exc
38
38
  res, format =
39
- { error: "Failed conversion #{format}: #{e}" }.to_json, 'json'
39
+ { error: "Failed conversion #{format}: #{exc}" }.to_json, 'json'
40
40
  end
41
41
 
42
42
  type, disposition = GEN_FORMATS[format]
@@ -219,7 +219,7 @@ class Marty::DataChange
219
219
  # "different".
220
220
  conv =
221
221
  Marty::DataConversion.convert_row(klass, input, ts)
222
- rescue StandardError => e
222
+ rescue StandardError => exc
223
223
  only_input << input
224
224
  next
225
225
  end
@@ -1,7 +1,7 @@
1
1
  class Marty::DataConversion
2
2
  EXCEL_START_DATE = Date.parse('1/1/1900') - 2
3
3
 
4
- FLOAT_PAT = /\A-?\d+(\.?\d+)?([eE][-+]?[0-9]+)?\z/
4
+ FLOAT_PAT = /^-?\d+(\.\d+)?$/
5
5
 
6
6
  PATS = {
7
7
  integer: /^-?\d+(\.0+)?$/,
@@ -58,13 +58,13 @@ class Marty::DataConversion
58
58
  begin
59
59
  v =~ FLOAT_PAT ? EXCEL_START_DATE + v.to_f :
60
60
  Mcfly.is_infinity(v) ? 'infinity' : v.to_date
61
- rescue StandardError => e
61
+ rescue StandardError => exc
62
62
  raise "date conversion failed for #{v.inspect}}"
63
63
  end
64
64
  when :datetime
65
65
  begin
66
66
  Mcfly.is_infinity(v) ? 'infinity' : v.to_datetime
67
- rescue StandardError => e
67
+ rescue StandardError => exc
68
68
  raise "datetime conversion failed for #{v.inspect}}"
69
69
  end
70
70
  when :numrange, :int4range, :int8range
@@ -98,6 +98,7 @@ class Marty::DataConversion
98
98
 
99
99
  @@associations[klass] ||= klass.reflect_on_all_associations.
100
100
  each_with_object({}) do |assoc, h|
101
+
101
102
  h[assoc.name.to_s] = {
102
103
  assoc_keys: assoc_keys(assoc.klass),
103
104
  assoc_class: assoc.klass,
@@ -77,9 +77,9 @@ module Marty
77
77
 
78
78
  Marty::DataConversion.create_or_update(klass, row, dt)
79
79
  end
80
- rescue StandardError => e
80
+ rescue StandardError => exc
81
81
  # to find problems with the importer, comment out the rescue block
82
- raise Error.new(e.to_s, [eline])
82
+ raise Error.new(exc.to_s, [eline])
83
83
  end
84
84
 
85
85
  ids = {}
@@ -96,8 +96,8 @@ module Marty
96
96
  # Validate affected rows if necessary
97
97
  klass.send(validation_function.to_sym, ids.keys) if
98
98
  validation_function
99
- rescue StandardError => e
100
- raise Error.new(e.to_s, [])
99
+ rescue StandardError => exc
100
+ raise Error.new(exc.to_s, [])
101
101
  end
102
102
 
103
103
  remainder_ids = cleaner_ids - ids.keys
@@ -6,8 +6,10 @@ module Mcfly::Model
6
6
  end
7
7
 
8
8
  module ClassMethods
9
- def hash_if_necessary(q, private)
10
- !private && q.is_a?(ActiveRecord::Base) ? make_openstruct(q) : q
9
+ def hash_if_necessary(q, to_hash)
10
+ return make_hash(q) if to_hash && q.is_a?(ActiveRecord::Base)
11
+
12
+ q
11
13
  end
12
14
 
13
15
  def base_mcfly_lookup(name, options = {}, &block)
@@ -41,7 +43,7 @@ module Mcfly::Model
41
43
 
42
44
  q = q.first if q.respond_to?(:first) && options[:mode] == :first
43
45
 
44
- hash_if_necessary(q, options[:private])
46
+ hash_if_necessary(q, options.fetch(:to_hash, false))
45
47
  end
46
48
  end
47
49
 
@@ -55,7 +57,7 @@ module Mcfly::Model
55
57
 
56
58
  def gen_mcfly_lookup(name, attrs, options = {})
57
59
  raise "bad options #{options.keys}" unless
58
- (options.keys - [:mode, :cache, :private]).empty?
60
+ (options.keys - [:mode, :cache, :private, :to_hash]).empty?
59
61
 
60
62
  mode = options.fetch(:mode, :first)
61
63
 
@@ -86,6 +88,7 @@ module Mcfly::Model
86
88
 
87
89
  base_mcfly_lookup(name, options + { sig: attrs.length + 1,
88
90
  mode: mode }) do |_t, *attr_list|
91
+
89
92
  attr_list_ids = attr_list.each_with_index.map do |_x, i|
90
93
  assoc.member?(attrs[i]) ?
91
94
  (attr_list[i] && attr_list[i].id) : attr_list[i]
@@ -134,7 +137,7 @@ module Mcfly::Model
134
137
 
135
138
  pc_name = "pc_#{name}".to_sym
136
139
 
137
- gen_mcfly_lookup(pc_name, pc_attrs, options + { private: true })
140
+ gen_mcfly_lookup(pc_name, pc_attrs, options + { private: true, to_hash: false })
138
141
 
139
142
  lpi = attrs.keys.index rel_attr
140
143
 
@@ -142,7 +145,7 @@ module Mcfly::Model
142
145
  raise "need #{rel_attr} argument" unless lpi
143
146
 
144
147
  # cache if mode is not nil
145
- priv = options[:private]
148
+ to_hash = options.fetch(:to_hash, false)
146
149
 
147
150
  # cache if mode is not explicitly set to nil or cache is true
148
151
  cache = options.fetch(:cache) { options.fetch(:mode, :first) }
@@ -165,7 +168,7 @@ module Mcfly::Model
165
168
  send(cat_attr_id)
166
169
 
167
170
  q = send(pc_name, ts, *args)
168
- hash_if_necessary(q, priv)
171
+ hash_if_necessary(q, to_hash)
169
172
  end
170
173
  end
171
174
  end