hobo 0.8.3 → 0.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES.txt +330 -0
- data/Manifest +12 -4
- data/Rakefile +4 -6
- data/dryml_generators/rapid/cards.dryml.erb +5 -1
- data/dryml_generators/rapid/forms.dryml.erb +8 -10
- data/dryml_generators/rapid/pages.dryml.erb +65 -36
- data/hobo.gemspec +28 -15
- data/lib/active_record/association_collection.rb +3 -22
- data/lib/hobo.rb +25 -258
- data/lib/hobo/accessible_associations.rb +131 -0
- data/lib/hobo/authentication_support.rb +15 -9
- data/lib/hobo/composite_model.rb +1 -1
- data/lib/hobo/controller.rb +7 -8
- data/lib/hobo/dryml.rb +9 -10
- data/lib/hobo/dryml/dryml_builder.rb +7 -1
- data/lib/hobo/dryml/dryml_doc.rb +161 -0
- data/lib/hobo/dryml/dryml_generator.rb +18 -9
- data/lib/hobo/dryml/part_context.rb +76 -42
- data/lib/hobo/dryml/tag_parameters.rb +1 -0
- data/lib/hobo/dryml/taglib.rb +2 -1
- data/lib/hobo/dryml/template.rb +39 -29
- data/lib/hobo/dryml/template_environment.rb +79 -37
- data/lib/hobo/dryml/template_handler.rb +66 -21
- data/lib/hobo/guest.rb +2 -10
- data/lib/hobo/hobo_helper.rb +125 -53
- data/lib/hobo/include_in_save.rb +0 -1
- data/lib/hobo/lifecycles.rb +54 -24
- data/lib/hobo/lifecycles/actions.rb +95 -31
- data/lib/hobo/lifecycles/creator.rb +18 -23
- data/lib/hobo/lifecycles/lifecycle.rb +86 -62
- data/lib/hobo/lifecycles/state.rb +1 -2
- data/lib/hobo/lifecycles/transition.rb +22 -28
- data/lib/hobo/model.rb +64 -176
- data/lib/hobo/model_controller.rb +67 -54
- data/lib/hobo/model_router.rb +5 -2
- data/lib/hobo/permissions.rb +397 -0
- data/lib/hobo/permissions/associations.rb +167 -0
- data/lib/hobo/scopes.rb +15 -38
- data/lib/hobo/scopes/association_proxy_extensions.rb +15 -5
- data/lib/hobo/scopes/automatic_scopes.rb +43 -18
- data/lib/hobo/scopes/named_scope_extensions.rb +2 -2
- data/lib/hobo/user.rb +10 -4
- data/lib/hobo/user_controller.rb +6 -5
- data/lib/hobo/view_hints.rb +58 -0
- data/rails_generators/hobo/hobo_generator.rb +7 -3
- data/rails_generators/hobo/templates/guest.rb +1 -13
- data/rails_generators/hobo_front_controller/hobo_front_controller_generator.rb +1 -1
- data/rails_generators/hobo_model/hobo_model_generator.rb +4 -2
- data/rails_generators/hobo_model/templates/hints.rb +4 -0
- data/rails_generators/hobo_model/templates/model.rb +8 -8
- data/rails_generators/hobo_model_controller/hobo_model_controller_generator.rb +10 -0
- data/rails_generators/hobo_model_controller/templates/controller.rb +1 -1
- data/rails_generators/hobo_rapid/templates/hobo-rapid.js +91 -56
- data/rails_generators/hobo_rapid/templates/lowpro.js +15 -15
- data/rails_generators/hobo_rapid/templates/reset.css +36 -3
- data/rails_generators/hobo_rapid/templates/themes/clean/public/stylesheets/clean.css +13 -17
- data/rails_generators/hobo_user_controller/templates/controller.rb +1 -1
- data/rails_generators/hobo_user_model/templates/model.rb +18 -16
- data/taglibs/core.dryml +60 -18
- data/taglibs/rapid.dryml +8 -401
- data/taglibs/rapid_core.dryml +586 -0
- data/taglibs/rapid_document_tags.dryml +28 -10
- data/taglibs/rapid_editing.dryml +92 -55
- data/taglibs/rapid_forms.dryml +406 -87
- data/taglibs/rapid_generics.dryml +1 -1
- data/taglibs/rapid_navigation.dryml +2 -1
- data/taglibs/rapid_pages.dryml +7 -16
- data/taglibs/rapid_plus.dryml +39 -14
- data/taglibs/rapid_support.dryml +1 -1
- data/taglibs/rapid_user_pages.dryml +14 -4
- data/tasks/{generate_tag_reference.rb → generate_tag_reference.rake} +49 -18
- data/tasks/hobo_tasks.rake +16 -0
- data/test/permissions/models/models.rb +134 -0
- data/test/permissions/models/schema.rb +55 -0
- data/test/permissions/models/test.sqlite3 +0 -0
- data/test/permissions/test_permissions.rb +436 -0
- metadata +27 -14
- data/lib/hobo/mass_assignment.rb +0 -64
- data/rails_generators/hobo/templates/patch_routing.rb +0 -30
- data/uninstall.rb +0 -1
@@ -2,13 +2,12 @@ module Hobo
|
|
2
2
|
|
3
3
|
module Lifecycles
|
4
4
|
|
5
|
-
class State < Struct.new(:name, :on_enter, :
|
5
|
+
class State < Struct.new(:name, :on_enter, :transitions_out)
|
6
6
|
|
7
7
|
include Actions
|
8
8
|
|
9
9
|
def initialize(*args)
|
10
10
|
super
|
11
|
-
self.transitions_in = []
|
12
11
|
self.transitions_out = []
|
13
12
|
end
|
14
13
|
|
@@ -2,57 +2,51 @@ module Hobo
|
|
2
2
|
|
3
3
|
module Lifecycles
|
4
4
|
|
5
|
-
class Transition < Struct.new(:lifecycle, :name, :
|
5
|
+
class Transition < Struct.new(:lifecycle, :name, :start_states, :end_state, :on_transition, :options)
|
6
6
|
|
7
7
|
include Actions
|
8
8
|
|
9
9
|
|
10
10
|
def initialize(*args)
|
11
11
|
super
|
12
|
+
self.name = name.to_sym
|
12
13
|
start_states.each do |from|
|
13
|
-
state = lifecycle.states[from
|
14
|
-
raise ArgumentError, "No such state '#{from}' in #{
|
14
|
+
state = lifecycle.states[from]
|
15
|
+
raise ArgumentError, "No such state '#{from}' in #{name} transition (#{lifecycle.model.name})" unless state
|
15
16
|
state.transitions_out << self
|
16
17
|
end
|
17
|
-
unless end_state.to_s == "destroy"
|
18
|
-
state = lifecycle.states[end_state.to_s]
|
19
|
-
raise ArgumentError, "No such state '#{end_state}' in '#{name}' transition (#{lifecycle.model.name})" unless state
|
20
|
-
state.transitions_in << self
|
21
|
-
end
|
22
18
|
lifecycle.transitions << self
|
23
19
|
end
|
24
20
|
|
25
21
|
|
26
|
-
def allowed?(record, user, attributes=nil)
|
27
|
-
prepare_and_check!(record, user, attributes) && true
|
28
|
-
end
|
29
|
-
|
30
|
-
|
31
22
|
def extract_attributes(attributes)
|
32
23
|
update_attributes = options.fetch(:update, [])
|
33
24
|
attributes & update_attributes
|
34
25
|
end
|
26
|
+
|
27
|
+
|
28
|
+
def change_state(record)
|
29
|
+
record.lifecycle.become(get_state(record, end_state))
|
30
|
+
end
|
35
31
|
|
36
32
|
|
37
33
|
def run!(record, user, attributes)
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
42
|
-
else
|
43
|
-
raise Hobo::Model::PermissionDeniedError
|
34
|
+
current_state = record.lifecycle.state_name
|
35
|
+
unless start_states.include?(current_state)
|
36
|
+
raise Hobo::Lifecycles::LifecycleError, "Transition #{record.class}##{name} cannot be run from the '#{current_state}' state"
|
44
37
|
end
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
38
|
+
record.lifecycle.active_step = self
|
39
|
+
record.with_acting_user(user) do
|
40
|
+
prepare!(record, attributes)
|
41
|
+
if can_run?(record)
|
42
|
+
if change_state(record)
|
43
|
+
fire_event(record, on_transition)
|
44
|
+
end
|
45
|
+
else
|
46
|
+
raise Hobo::PermissionDeniedError
|
47
|
+
end
|
53
48
|
end
|
54
49
|
end
|
55
|
-
alias_method_chain :set_or_check_who!, :key
|
56
50
|
|
57
51
|
|
58
52
|
def parameters
|
data/lib/hobo/model.rb
CHANGED
@@ -2,7 +2,6 @@ module Hobo
|
|
2
2
|
|
3
3
|
module Model
|
4
4
|
|
5
|
-
class PermissionDeniedError < RuntimeError; end
|
6
5
|
class NoNameError < RuntimeError; end
|
7
6
|
|
8
7
|
NAME_FIELD_GUESS = %w(name title)
|
@@ -13,8 +12,6 @@ module Hobo
|
|
13
12
|
def self.included(base)
|
14
13
|
base.extend(ClassMethods)
|
15
14
|
|
16
|
-
included_in_class_callbacks(base)
|
17
|
-
|
18
15
|
register_model(base)
|
19
16
|
|
20
17
|
patch_will_paginate
|
@@ -23,18 +20,15 @@ module Hobo
|
|
23
20
|
inheriting_cattr_reader :default_order
|
24
21
|
alias_method_chain :attributes=, :hobo_type_conversion
|
25
22
|
|
26
|
-
|
27
|
-
|
28
|
-
bool_attr_accessor :exempt_from_edit_checks
|
29
|
-
|
23
|
+
include Hobo::Permissions
|
30
24
|
include Hobo::Lifecycles::ModelExtensions
|
31
25
|
include Hobo::FindFor
|
32
|
-
include Hobo::
|
26
|
+
include Hobo::AccessibleAssociations
|
33
27
|
end
|
34
28
|
|
35
29
|
class << base
|
36
30
|
alias_method_chain :belongs_to, :creator_metadata
|
37
|
-
alias_method_chain :belongs_to, :
|
31
|
+
alias_method_chain :belongs_to, :test_methods
|
38
32
|
alias_method_chain :attr_accessor, :creator_metadata
|
39
33
|
|
40
34
|
alias_method_chain :has_one, :new_method
|
@@ -49,10 +43,12 @@ module Hobo
|
|
49
43
|
end
|
50
44
|
|
51
45
|
base.fields # force hobofields to load
|
46
|
+
|
47
|
+
included_in_class_callbacks(base)
|
52
48
|
end
|
53
49
|
|
54
50
|
def self.patch_will_paginate
|
55
|
-
if defined?(WillPaginate) && !WillPaginate::Collection.respond_to?(:member_class)
|
51
|
+
if defined?(WillPaginate::Collection) && !WillPaginate::Collection.respond_to?(:member_class)
|
56
52
|
|
57
53
|
WillPaginate::Collection.class_eval do
|
58
54
|
attr_accessor :member_class, :origin, :origin_attribute
|
@@ -92,16 +88,45 @@ module Hobo
|
|
92
88
|
# ...but only return the ones that registered themselves
|
93
89
|
@model_names.*.constantize
|
94
90
|
end
|
91
|
+
|
92
|
+
|
93
|
+
def self.find_by_typed_id(typed_id)
|
94
|
+
return nil if typed_id == 'nil'
|
95
|
+
|
96
|
+
_, name, id, attr = *typed_id.match(/^([^:]+)(?::([^:]+)(?::([^:]+))?)?$/)
|
97
|
+
raise ArgumentError.new("invalid typed-id: #{typed_id}") unless name
|
98
|
+
|
99
|
+
model_class = name.camelize.safe_constantize or raise ArgumentError.new("no such class in typed-id: #{typed_id}")
|
100
|
+
return nil unless model_class
|
101
|
+
|
102
|
+
if id
|
103
|
+
obj = model_class.find(id)
|
104
|
+
# Optimise: can we use eager loading in the situation where the attr is a belongs_to?
|
105
|
+
# We used to, but hit a bug in AR
|
106
|
+
attr ? obj.send(attr) : obj
|
107
|
+
else
|
108
|
+
model_class
|
109
|
+
end
|
110
|
+
end
|
95
111
|
|
96
112
|
|
97
113
|
def self.enable
|
114
|
+
require 'active_record/association_collection'
|
115
|
+
require 'active_record/association_proxy'
|
116
|
+
require 'active_record/association_reflection'
|
117
|
+
|
98
118
|
ActiveRecord::Base.class_eval do
|
99
119
|
def self.hobo_model
|
100
120
|
include Hobo::Model
|
101
121
|
fields # force hobofields to load
|
102
122
|
end
|
103
|
-
|
123
|
+
def self.hobo_user_model
|
124
|
+
include Hobo::Model
|
125
|
+
include Hobo::User
|
126
|
+
end
|
104
127
|
alias_method :has_hobo_method?, :respond_to_without_attributes?
|
128
|
+
|
129
|
+
Hobo::Permissions.enable
|
105
130
|
end
|
106
131
|
end
|
107
132
|
|
@@ -131,45 +156,6 @@ module Hobo
|
|
131
156
|
end
|
132
157
|
|
133
158
|
|
134
|
-
def user_find(user, *args)
|
135
|
-
record = find(*args)
|
136
|
-
yield(record) if block_given?
|
137
|
-
raise PermissionDeniedError unless Hobo.can_view?(user, record)
|
138
|
-
record
|
139
|
-
end
|
140
|
-
|
141
|
-
|
142
|
-
def user_new(user, attributes={})
|
143
|
-
record = new(attributes) {|r| r.acting_user = user; yield if block_given? }
|
144
|
-
allowed = record.user_changes(user)
|
145
|
-
record.acting_user = nil
|
146
|
-
allowed && record
|
147
|
-
end
|
148
|
-
|
149
|
-
|
150
|
-
def user_new!(user, attributes={})
|
151
|
-
user_new(user, attributes) or raise PermissionDeniedError
|
152
|
-
end
|
153
|
-
|
154
|
-
|
155
|
-
def user_create(user, attributes={})
|
156
|
-
record = new(attributes)
|
157
|
-
record.user_save_changes(user)
|
158
|
-
record
|
159
|
-
end
|
160
|
-
|
161
|
-
|
162
|
-
def user_can_create?(user, attributes={})
|
163
|
-
record = new(attributes)
|
164
|
-
record.user_changes(user)
|
165
|
-
end
|
166
|
-
|
167
|
-
|
168
|
-
def user_update(user, id, attributes={})
|
169
|
-
find(id).user_save_changes(user, attributes)
|
170
|
-
end
|
171
|
-
|
172
|
-
|
173
159
|
def name_attribute
|
174
160
|
@name_attribute ||= begin
|
175
161
|
names = columns.*.name + public_instance_methods
|
@@ -212,20 +198,26 @@ module Hobo
|
|
212
198
|
belongs_to_without_creator_metadata(name, options, &block)
|
213
199
|
end
|
214
200
|
|
215
|
-
def
|
216
|
-
|
201
|
+
def belongs_to_with_test_methods(name, options={}, &block)
|
202
|
+
belongs_to_without_test_methods(name, options, &block)
|
217
203
|
refl = reflections[name]
|
218
204
|
if options[:polymorphic]
|
219
205
|
class_eval %{
|
220
206
|
def #{name}_is?(target)
|
221
207
|
target.id == self.#{refl.primary_key_name} && target.class.name == self.#{refl.options[:foreign_type]}
|
222
208
|
end
|
209
|
+
def #{name}_changed?
|
210
|
+
#{refl.primary_key_name}_changed? || #{refl.options[:foreign_type]}_changed?
|
211
|
+
end
|
223
212
|
}
|
224
213
|
else
|
225
214
|
class_eval %{
|
226
215
|
def #{name}_is?(target)
|
227
216
|
target.id == self.#{refl.primary_key_name}
|
228
217
|
end
|
218
|
+
def #{name}_changed?
|
219
|
+
#{refl.primary_key_name}_changed?
|
220
|
+
end
|
229
221
|
}
|
230
222
|
end
|
231
223
|
end
|
@@ -341,15 +333,17 @@ module Hobo
|
|
341
333
|
r.source_reflection == join_to_self
|
342
334
|
end
|
343
335
|
else
|
344
|
-
# Find the :belongs_to that corresponds to a :has_many or vice versa
|
336
|
+
# Find the :belongs_to that corresponds to a :has_one / :has_many or vice versa
|
337
|
+
|
338
|
+
reverse_macros = case refl.macro
|
339
|
+
when :has_many, :has_one
|
340
|
+
[:belongs_to]
|
341
|
+
when :belongs_to
|
342
|
+
[:has_many, :has_one]
|
343
|
+
end
|
345
344
|
|
346
|
-
reverse_macro = if refl.macro == :has_many
|
347
|
-
:belongs_to
|
348
|
-
elsif refl.macro == :belongs_to
|
349
|
-
:has_many
|
350
|
-
end
|
351
345
|
refl.klass.reflections.values.find do |r|
|
352
|
-
r.macro
|
346
|
+
r.macro.in?(reverse_macros) &&
|
353
347
|
r.klass == self &&
|
354
348
|
!r.options[:conditions] &&
|
355
349
|
r.primary_key_name == refl.primary_key_name
|
@@ -376,7 +370,7 @@ module Hobo
|
|
376
370
|
end
|
377
371
|
|
378
372
|
|
379
|
-
def respond_to?(method)
|
373
|
+
def respond_to?(method, include_private=false)
|
380
374
|
super || create_automatic_scope(method)
|
381
375
|
end
|
382
376
|
|
@@ -396,6 +390,12 @@ module Hobo
|
|
396
390
|
def typed_id
|
397
391
|
HoboFields.to_name(self) || name.underscore.gsub("/", "__")
|
398
392
|
end
|
393
|
+
|
394
|
+
|
395
|
+
def view_hints
|
396
|
+
class_name = "#{name}Hints"
|
397
|
+
class_name.safe_constantize or Object.class_eval("class #{class_name} < Hobo::ViewHints; end; #{class_name}")
|
398
|
+
end
|
399
399
|
|
400
400
|
|
401
401
|
end # --- of ClassMethods --- #
|
@@ -411,8 +411,8 @@ module Hobo
|
|
411
411
|
|
412
412
|
def to_param
|
413
413
|
name_attr = self.class.name_attribute and name = send(name_attr)
|
414
|
-
if name_attr && !name.blank?
|
415
|
-
readable = name.to_s.downcase.gsub(/[^a-z0-9]+/, '-').gsub(/-+$/, '').gsub(
|
414
|
+
if name_attr && !name.blank? && id.is_a?(Fixnum)
|
415
|
+
readable = name.to_s.downcase.gsub(/[^a-z0-9]+/, '-').gsub(/-+$/, '').gsub(/^-+/, '').split('-')[0..5].join('-')
|
416
416
|
@to_param ||= "#{id}-#{readable}"
|
417
417
|
else
|
418
418
|
id.to_s
|
@@ -420,73 +420,6 @@ module Hobo
|
|
420
420
|
end
|
421
421
|
|
422
422
|
|
423
|
-
def with_acting_user(user)
|
424
|
-
old = acting_user
|
425
|
-
self.acting_user = user
|
426
|
-
result = yield
|
427
|
-
self.acting_user = old
|
428
|
-
result
|
429
|
-
end
|
430
|
-
|
431
|
-
|
432
|
-
def user_changes(user, changes={})
|
433
|
-
with_acting_user user do
|
434
|
-
if new_record?
|
435
|
-
self.attributes = changes
|
436
|
-
set_creator(user)
|
437
|
-
Hobo.can_create?(user, self)
|
438
|
-
else
|
439
|
-
original = duplicate
|
440
|
-
# 'duplicate' can cause these to be set, but they can conflict
|
441
|
-
# with the changes so we clear them
|
442
|
-
clear_aggregation_cache
|
443
|
-
clear_association_cache
|
444
|
-
|
445
|
-
self.attributes = changes
|
446
|
-
|
447
|
-
Hobo.can_update?(user, original, self)
|
448
|
-
end
|
449
|
-
end
|
450
|
-
end
|
451
|
-
|
452
|
-
|
453
|
-
def user_changes!(user, changes={})
|
454
|
-
user_changes(user, changes) or raise PermissionDeniedError
|
455
|
-
end
|
456
|
-
|
457
|
-
|
458
|
-
def user_can_create?(user, attributes={})
|
459
|
-
raise ArgumentError, "Called #user_can_create? on existing record" unless new_record?
|
460
|
-
user_changes(user, attributes)
|
461
|
-
end
|
462
|
-
|
463
|
-
|
464
|
-
def user_save_changes(user, changes={})
|
465
|
-
with_acting_user user do
|
466
|
-
user_changes!(user, changes)
|
467
|
-
save
|
468
|
-
end
|
469
|
-
end
|
470
|
-
|
471
|
-
|
472
|
-
def user_save(user)
|
473
|
-
user_save_changes(user)
|
474
|
-
end
|
475
|
-
|
476
|
-
|
477
|
-
def user_view(user, field=nil)
|
478
|
-
raise PermissionDeniedError, self.inspect unless Hobo.can_view?(user, self, field)
|
479
|
-
end
|
480
|
-
|
481
|
-
|
482
|
-
def user_destroy(user)
|
483
|
-
with_acting_user user do
|
484
|
-
raise PermissionDeniedError unless Hobo.can_delete?(user, self)
|
485
|
-
destroy
|
486
|
-
end
|
487
|
-
end
|
488
|
-
|
489
|
-
|
490
423
|
def dependent_on
|
491
424
|
self.class.dependent_on.map { |assoc| send(assoc) }
|
492
425
|
end
|
@@ -567,7 +500,7 @@ module Hobo
|
|
567
500
|
|
568
501
|
|
569
502
|
def typed_id
|
570
|
-
"#{self.class.name.underscore}
|
503
|
+
"#{self.class.name.underscore}:#{self.id}" if id
|
571
504
|
end
|
572
505
|
|
573
506
|
|
@@ -583,19 +516,8 @@ module Hobo
|
|
583
516
|
private
|
584
517
|
|
585
518
|
|
586
|
-
def parse_datetime(s)
|
587
|
-
defined?(Chronic) ? Chronic.parse(s) : Time.parse(s)
|
588
|
-
end
|
589
|
-
|
590
|
-
|
591
519
|
def convert_type_for_mass_assignment(field_type, value)
|
592
|
-
if field_type.is_a?(Class)
|
593
|
-
convert_record_reference_for_mass_assignment(field_type, value)
|
594
|
-
|
595
|
-
elsif field_type.is_a?(ActiveRecord::Reflection::AssociationReflection)
|
596
|
-
convert_collection_for_mass_assignment(field_type, value)
|
597
|
-
|
598
|
-
elsif !field_type.is_a?(Class)
|
520
|
+
if !field_type.is_a?(Class)
|
599
521
|
value
|
600
522
|
|
601
523
|
elsif field_type <= Date
|
@@ -606,9 +528,6 @@ module Hobo
|
|
606
528
|
else
|
607
529
|
Date.new(*parts)
|
608
530
|
end
|
609
|
-
elsif value.is_a? String
|
610
|
-
dt = parse_datetime(value)
|
611
|
-
dt && dt.to_date
|
612
531
|
else
|
613
532
|
value
|
614
533
|
end
|
@@ -616,8 +535,6 @@ module Hobo
|
|
616
535
|
elsif field_type <= Time || field_type <= ActiveSupport::TimeWithZone
|
617
536
|
if value.is_a? Hash
|
618
537
|
Time.local(*(%w{year month day hour minute}.map{|s| value[s].to_i}))
|
619
|
-
elsif value.is_a? String
|
620
|
-
parse_datetime(value)
|
621
538
|
else
|
622
539
|
value
|
623
540
|
end
|
@@ -632,35 +549,6 @@ module Hobo
|
|
632
549
|
end
|
633
550
|
|
634
551
|
|
635
|
-
def convert_record_reference_for_mass_assignment(klass, value)
|
636
|
-
if value.is_a?(String)
|
637
|
-
if value.starts_with?('@')
|
638
|
-
# TODO: This @foo_1 feature is rarely (never?) used - get rid of it
|
639
|
-
Hobo.object_from_dom_id(value[1..-1])
|
640
|
-
else
|
641
|
-
klass.named(value)
|
642
|
-
end
|
643
|
-
else
|
644
|
-
value
|
645
|
-
end
|
646
|
-
end
|
647
|
-
|
648
|
-
|
649
|
-
def convert_collection_for_mass_assignment(reflection, value)
|
650
|
-
klass = reflection.klass
|
651
|
-
if klass.try.name_attribute && value.is_a?(Array)
|
652
|
-
value.map do |x|
|
653
|
-
if x.is_a?(String)
|
654
|
-
klass.named(x) unless x.blank?
|
655
|
-
else
|
656
|
-
x
|
657
|
-
end
|
658
|
-
end.compact
|
659
|
-
else
|
660
|
-
value
|
661
|
-
end
|
662
|
-
end
|
663
|
-
|
664
552
|
end
|
665
553
|
|
666
554
|
end
|