infopark_reactor 1.25.2 → 1.27.0.rc8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +25 -0
  3. data/.rubocop_todo.yml +363 -0
  4. data/Rakefile +10 -13
  5. data/app/models/rails_connector/abstract_obj.rb +2 -1
  6. data/config/routes.rb +0 -1
  7. data/infopark_reactor.gemspec +16 -15
  8. data/lib/generators/cm/migration/migration_generator.rb +4 -8
  9. data/lib/infopark_reactor.rb +43 -69
  10. data/lib/reactor/already_released.rb +1 -2
  11. data/lib/reactor/attributes.rb +94 -270
  12. data/lib/reactor/attributes/date_serializer.rb +23 -16
  13. data/lib/reactor/attributes/html_serializer.rb +6 -5
  14. data/lib/reactor/attributes/link_list_extender.rb +10 -8
  15. data/lib/reactor/attributes/link_list_from_accessor.rb +2 -1
  16. data/lib/reactor/attributes/link_list_from_attr_values.rb +2 -1
  17. data/lib/reactor/attributes/link_list_serializer.rb +8 -7
  18. data/lib/reactor/attributes_handlers.rb +164 -0
  19. data/lib/reactor/cache/permission.rb +6 -9
  20. data/lib/reactor/cache/user.rb +3 -6
  21. data/lib/reactor/cm/attribute.rb +16 -16
  22. data/lib/reactor/cm/attribute_group.rb +18 -21
  23. data/lib/reactor/cm/blob_too_small_error.rb +2 -2
  24. data/lib/reactor/cm/bridge.rb +6 -9
  25. data/lib/reactor/cm/channel.rb +3 -4
  26. data/lib/reactor/cm/editorial_group.rb +2 -9
  27. data/lib/reactor/cm/group.rb +30 -43
  28. data/lib/reactor/cm/job.rb +77 -0
  29. data/lib/reactor/cm/language.rb +21 -22
  30. data/lib/reactor/cm/link.rb +38 -40
  31. data/lib/reactor/cm/live_group.rb +2 -9
  32. data/lib/reactor/cm/log_entry.rb +22 -21
  33. data/lib/reactor/cm/missing_credentials.rb +3 -2
  34. data/lib/reactor/cm/multi_xml_request.rb +22 -25
  35. data/lib/reactor/cm/obj.rb +161 -152
  36. data/lib/reactor/cm/obj_class.rb +52 -51
  37. data/lib/reactor/cm/object_base.rb +26 -21
  38. data/lib/reactor/cm/permissions.rb +7 -7
  39. data/lib/reactor/cm/user.rb +43 -51
  40. data/lib/reactor/cm/workflow.rb +11 -12
  41. data/lib/reactor/cm/xml_attribute.rb +10 -19
  42. data/lib/reactor/cm/xml_markup.rb +7 -10
  43. data/lib/reactor/cm/xml_multi_request_error.rb +1 -3
  44. data/lib/reactor/cm/xml_request.rb +21 -29
  45. data/lib/reactor/cm/xml_request_error.rb +1 -3
  46. data/lib/reactor/cm/xml_response.rb +8 -16
  47. data/lib/reactor/cm/xml_single_request_error.rb +3 -5
  48. data/lib/reactor/configuration.rb +1 -3
  49. data/lib/reactor/engine.rb +5 -10
  50. data/lib/reactor/legacy.rb +8 -9
  51. data/lib/reactor/link/external.rb +8 -5
  52. data/lib/reactor/link/internal.rb +8 -5
  53. data/lib/reactor/link/temporary_link.rb +18 -19
  54. data/lib/reactor/main.rb +11 -15
  55. data/lib/reactor/migration.rb +52 -47
  56. data/lib/reactor/no_working_version.rb +1 -2
  57. data/lib/reactor/not_permitted.rb +1 -2
  58. data/lib/reactor/permission.rb +36 -38
  59. data/lib/reactor/persistence.rb +105 -159
  60. data/lib/reactor/plans/common_attribute.rb +7 -7
  61. data/lib/reactor/plans/common_attribute_group.rb +6 -6
  62. data/lib/reactor/plans/common_channel.rb +6 -6
  63. data/lib/reactor/plans/common_group.rb +7 -14
  64. data/lib/reactor/plans/common_job.rb +32 -0
  65. data/lib/reactor/plans/common_obj_class.rb +11 -11
  66. data/lib/reactor/plans/create_attribute.rb +1 -3
  67. data/lib/reactor/plans/create_attribute_group.rb +1 -3
  68. data/lib/reactor/plans/create_channel.rb +2 -3
  69. data/lib/reactor/plans/create_group.rb +3 -10
  70. data/lib/reactor/plans/create_job.rb +22 -0
  71. data/lib/reactor/plans/create_obj.rb +12 -14
  72. data/lib/reactor/plans/create_obj_class.rb +1 -2
  73. data/lib/reactor/plans/delete_attribute.rb +1 -3
  74. data/lib/reactor/plans/delete_attribute_group.rb +2 -4
  75. data/lib/reactor/plans/delete_channel.rb +4 -4
  76. data/lib/reactor/plans/delete_group.rb +2 -9
  77. data/lib/reactor/plans/delete_job.rb +23 -0
  78. data/lib/reactor/plans/delete_obj.rb +3 -4
  79. data/lib/reactor/plans/delete_obj_class.rb +1 -2
  80. data/lib/reactor/plans/prepared.rb +3 -4
  81. data/lib/reactor/plans/rename_group.rb +4 -11
  82. data/lib/reactor/plans/rename_obj_class.rb +1 -2
  83. data/lib/reactor/plans/update_attribute.rb +1 -3
  84. data/lib/reactor/plans/update_attribute_group.rb +2 -4
  85. data/lib/reactor/plans/update_group.rb +2 -9
  86. data/lib/reactor/plans/update_job.rb +27 -0
  87. data/lib/reactor/plans/update_obj.rb +6 -7
  88. data/lib/reactor/plans/update_obj_class.rb +0 -2
  89. data/lib/reactor/rc_independent.rb +0 -1
  90. data/lib/reactor/session.rb +27 -31
  91. data/lib/reactor/session/observers.rb +3 -5
  92. data/lib/reactor/session/user.rb +6 -7
  93. data/lib/reactor/session_helper/auth_filter.rb +9 -0
  94. data/lib/reactor/session_helper/auth_helper.rb +24 -0
  95. data/lib/reactor/session_helper/rsession_helper.rb +16 -0
  96. data/lib/reactor/session_helper/session_state.rb +31 -0
  97. data/lib/reactor/streaming_upload.rb +0 -1
  98. data/lib/reactor/sudo.rb +2 -3
  99. data/lib/reactor/support/link_matcher.rb +8 -7
  100. data/lib/reactor/tools/migrator.rb +30 -35
  101. data/lib/reactor/tools/response_handler/xml_attribute.rb +37 -27
  102. data/lib/reactor/tools/smart_xml_logger.rb +20 -22
  103. data/lib/reactor/tools/sower.rb +22 -23
  104. data/lib/reactor/tools/uploader.rb +12 -17
  105. data/lib/reactor/tools/versioner.rb +29 -30
  106. data/lib/reactor/tools/where_query.rb +11 -14
  107. data/lib/reactor/tools/workflow_generator.rb +26 -28
  108. data/lib/reactor/tools/xml_attributes.rb +7 -14
  109. data/lib/reactor/tools/xpath_extractor.rb +2 -1
  110. data/lib/reactor/validations.rb +20 -16
  111. data/lib/reactor/version.rb +1 -2
  112. data/lib/reactor/workflow.rb +10 -33
  113. data/lib/reactor/workflow/comment.rb +28 -0
  114. data/lib/reactor/workflow/empty.rb +0 -1
  115. data/lib/reactor/workflow/standard.rb +4 -3
  116. data/lib/tasks/cm_migrate.rake +3 -3
  117. data/lib/tasks/cm_seeds.rake +9 -16
  118. metadata +81 -39
  119. data/app/models/rails_connector/abstract_model.rb +0 -7
  120. data/app/models/rails_connector/attribute.rb +0 -94
  121. data/app/models/rails_connector/blob_mapping.rb +0 -16
  122. data/app/models/rails_connector/channel.rb +0 -41
  123. data/app/models/rails_connector/content.rb +0 -12
  124. data/app/models/rails_connector/obj_class.rb +0 -158
  125. data/app/models/rails_connector/obj_class_attr.rb +0 -5
  126. data/app/models/rails_connector/object_with_meta_data.rb +0 -18
  127. data/lib/rails_connector/meta/eager_loader.rb +0 -91
  128. data/lib/reactor/rails_connector_meta.rb +0 -149
  129. data/lib/reactor/session_helper.rb +0 -72
@@ -1,7 +0,0 @@
1
- module RailsConnector
2
- AbstractModel = begin
3
- ::RailsConnector::InfoparkBase
4
- rescue NameError
5
- ::RailsConnector::CmsBaseModel
6
- end
7
- end
@@ -1,94 +0,0 @@
1
- # -*- encoding : utf-8 -*-
2
- module RailsConnector
3
-
4
- # The methods date?, enum?, html?, linklist?, markdown?, multienum?, string? and
5
- # text? are created by meta programming have no documentation of their own.
6
- # Warning: Dependent on the setup of your DB replication, most tables
7
- # with meta information will not be available on your live system!
8
- class Attribute < RailsConnector::AbstractModel
9
-
10
- # The possible types of an attribute.
11
- TYPES = %w{date enum html linklist markdown multienum string text}
12
-
13
- self.primary_key = :attribute_id
14
-
15
- has_and_belongs_to_many :obj_class_definitions, :class_name => '::RailsConnector::ObjClass',
16
- :join_table => "#{table_name_prefix}obj_class_attrs"
17
-
18
- alias_method :obj_class_defs, :obj_class_definitions
19
- alias_attribute :name, :attribute_name
20
-
21
- # The (human readable) title.
22
- def title(language = :de)
23
- load_blob_data
24
- @blob_data['titles'].presence && @blob_data['titles'][language.to_s]
25
- end
26
-
27
- # The description of the attribute.
28
- def help_text(language = :de)
29
- load_blob_data
30
- @blob_data['helpTexts'].presence && @blob_data['helpTexts'][language.to_s]
31
- end
32
-
33
- # Searchable in Content Manager.
34
- def searchable_in_cm?
35
- load_blob_data
36
- @blob_data['isSearchableInCM'].to_i != 0
37
- end
38
-
39
- # Returns the possible values if attribute is of type `enum' or `multienum'.
40
- def values
41
- load_blob_data
42
- @blob_data['values']
43
- end
44
-
45
- def max_size
46
- load_blob_data
47
- @blob_data["maxSize"]
48
- end
49
-
50
- def min_size
51
- load_blob_data
52
- @blob_data["minSize"]
53
- end
54
-
55
- TYPES.each do |type|
56
- self.class_eval <<EOM, __FILE__, __LINE__ + 1
57
- def #{type}?
58
- self.attribute_type == "#{type}"
59
- end
60
- EOM
61
- end
62
-
63
- # Convenience method for find_by_attribute_name
64
- def self.find_by_name(*args)
65
- self.find_by_attribute_name(*args)
66
- end
67
-
68
- # Returns the blob as a JSON object.
69
- def self.read_blob_data(name) #:nodoc:
70
- blob = RailsConnector::Meta.hello_im_rails_and_im_retarted_so_please_be_patient do # these queries really pollute our logs!
71
- blob_name = if RailsConnector::BlobMapping.exists?
72
- RailsConnector::BlobMapping.get_fingerprint("#{name}.jsonAttributeDict")
73
- else
74
- "#{name}.jsonAttributeDict"
75
- end
76
-
77
- RailsConnector::Blob.find_without_excluded_blob_data(blob_name)
78
- end
79
-
80
- return {} unless blob && blob.blob_data?
81
-
82
- JSON.parse(blob.blob_data)
83
- end
84
-
85
- private
86
-
87
- # load attribute details from blob
88
- def load_blob_data #:nodoc:
89
- @blob_data ||= self.class.read_blob_data(self.attribute_name)
90
- end
91
-
92
- end
93
-
94
- end
@@ -1,16 +0,0 @@
1
- # -*- encoding : utf-8 -*-
2
- module RailsConnector
3
- class BlobMapping < RailsConnector::AbstractModel
4
- def self.exists?
5
- self.table_exists?
6
- end
7
-
8
- def self.get_fingerprint(name)
9
- find_by_blob_name(name).fingerprint
10
- end
11
-
12
- def self.get_fingerprint_map(blob_names)
13
- Hash[self.where(:blob_name => blob_names).select([:blob_name, :fingerprint]).map {|b| [b.blob_name, b.fingerprint] }]
14
- end
15
- end
16
- end
@@ -1,41 +0,0 @@
1
- # -*- encoding : utf-8 -*-
2
- # @author Anton Mezin
3
- module RailsConnector
4
- class Channel < AbstractModel
5
- self.primary_key = "channel_name"
6
-
7
- def self.table_name
8
- "#{table_name_prefix}" "channels"
9
- end
10
-
11
- has_many :news, :class_name => 'News', :foreign_key => 'channel_name'
12
-
13
- if ::Rails::VERSION::MAJOR == 4
14
-
15
- has_many :active_news,
16
- lambda { where(['valid_from <= :now AND valid_until >= :now', {:now => Time.now.to_s(:number)}]) },
17
- :class_name => 'News', :foreign_key => 'channel_name'
18
-
19
- if ::Rails::VERSION::MINOR >= 1
20
-
21
- def self.scoped
22
- self.where(nil)
23
- end
24
-
25
- end
26
-
27
- elsif ::Rails::VERSION::MAJOR == 3
28
-
29
- has_many :active_news, :class_name => 'News', :foreign_key => 'channel_name',
30
- :conditions => ['valid_from <= :now AND valid_until >= :now', {:now => Time.now.to_s(:number)}]
31
-
32
- end
33
-
34
- has_many :objects, :through => :news
35
-
36
- def self.with_prefix(prefix)
37
- scoped.where(["channel_name LIKE ?", "#{prefix}%"])
38
- end
39
-
40
- end
41
- end
@@ -1,12 +0,0 @@
1
- # -*- encoding : utf-8 -*-
2
- module RailsConnector
3
-
4
- # This class allows us to read out the editor of an Obj,
5
- # if it has edited content
6
- class Content < RailsConnector::AbstractModel
7
-
8
- self.primary_key = :content_id
9
-
10
- end
11
-
12
- end
@@ -1,158 +0,0 @@
1
- # -*- encoding : utf-8 -*-
2
- module RailsConnector
3
-
4
- # This class is used to read out the custom attributes,
5
- # mandatory attributes and titles of an Obj.
6
- # Warning: Dependent on the setup of your DB replication, most tables
7
- # with meta information will not be available on your live system!
8
- class ObjClass < RailsConnector::AbstractModel
9
-
10
- self.primary_key = :obj_class_id
11
-
12
- if Reactor.rails4_x?
13
- has_many :custom_attributes_jt, :class_name => '::RailsConnector::ObjClassAttr', :foreign_key => 'obj_class_id', :primary_key => 'obj_class_id'
14
- has_many :custom_attributes_raw, :through => :custom_attributes_jt, :source => :custom_attributes_raw
15
- else
16
- has_and_belongs_to_many :custom_attributes_raw, :class_name => '::RailsConnector::Attribute',
17
- :join_table => "#{table_name_prefix}obj_class_attrs"
18
- end
19
-
20
- alias_attribute :name, :obj_class_name
21
-
22
- # Returns the title of the file format or nil, if it was not set.
23
- def title(language)
24
- self.titles[language.to_s].presence
25
- end
26
-
27
- # Returns all titles as a Hash.
28
- def titles
29
- load_blob_data
30
- @blob_data['titles'] || {}
31
- end
32
-
33
- def attribute_groups
34
- load_blob_data
35
- @blob_data['attributeGroups'] || []
36
- end
37
-
38
- def valid_sub_obj_classes
39
- load_blob_data
40
- @blob_data['validSubObjClasses'] || []
41
- end
42
-
43
- # returns channel feature is_activate?
44
- def can_create_news_items?
45
- load_blob_data
46
- @blob_data['canCreateNewsItems'].to_i != 0
47
- end
48
-
49
- def enabled?
50
- is_enabled == 1
51
- end
52
-
53
- # Returns the custom Ruby class or RailsConnector::AbstractObj.
54
- def ruby_class
55
- # this must be the same algorithm that the rest of the RailsConnector uses!
56
- RailsConnector::AbstractObj.compute_type(self.name)
57
- end
58
-
59
- # Returns true, if a custom Ruby class exists.
60
- def has_custom_ruby_class?
61
- self.ruby_class.present? && self.ruby_class != RailsConnector::AbstractObj &&
62
- self.ruby_class.ancestors.include?(RailsConnector::AbstractObj)
63
- end
64
-
65
- # Returns the custom attributes in the form of a Hash.
66
- def custom_attributes
67
- # return the cached data
68
- return @custom_attributes if @custom_attributes
69
-
70
- # create a Hash (with indifferent access) out of an Array of ActiveRecord objects
71
- @custom_attributes = self.custom_attributes_raw.map do |attr|
72
- {attr.attribute_name => attr}
73
- end.reduce(HashWithIndifferentAccess.new, &:merge)
74
- end
75
-
76
- # Returns true, if the Obj Class has an attribute of the given name.
77
- def custom_attribute?(attr)
78
- self.custom_attributes.key?(attr)
79
- end
80
-
81
- # Returns an Array of String of all mandatory attributes found for this ObjClass,
82
- # no matter if it is a custom or built-in attribute. Built-in attributes
83
- # are underscored (valid_from, not validFrom).
84
- # Possible +options+ are:
85
- # <tt>:only_custom_attributes</tt>:: Return only custom attributes, omit
86
- # built-in attributes like content_type or valid_from.
87
- def mandatory_attribute_names(options = {})
88
- only_custom_attributes ||= options[:only_custom_attributes] || false
89
- build_mandatory_attribute_arrays
90
- return @mandatory_custom_attributes if only_custom_attributes
91
- @mandatory_attributes
92
- end
93
-
94
- # Returns true, if the file format has an mandatory attribute of the given name.
95
- def mandatory_attribute?(attr)
96
- self.mandatory_attribute_names.include?(attr.to_s)
97
- end
98
-
99
- # Convenience method for find_by_obj_class_name
100
- def self.find_by_name(*args)
101
- self.find_by_obj_class_name(*args)
102
- end
103
-
104
- # Reads a whole bunch of data, where only some of it is useful
105
- # in a Rails application:
106
- # attributeGroups, availableBlobEditors, bodyTemplateName,
107
- # canCreateNewsItems, completionCheck, mandatoryAttributes,
108
- # presetAttributes, recordSetCallback, titles, validSubObjClassCheck,
109
- # workflowModification
110
- def self.read_blob_data(name) #:nodoc:
111
- blob = RailsConnector::Meta.hello_im_rails_and_im_retarted_so_please_be_patient do # these queries really pollute our logs!
112
- blob_name = if RailsConnector::BlobMapping.exists?
113
- RailsConnector::BlobMapping.get_fingerprint("#{name}.jsonObjClassDict")
114
- else
115
- "#{name}.jsonObjClassDict"
116
- end
117
-
118
- RailsConnector::Blob.find_without_excluded_blob_data(blob_name)
119
- end
120
-
121
- return {} unless blob && blob.blob_data?
122
-
123
- JSON.parse(blob.blob_data)
124
- end
125
-
126
- private
127
-
128
- def load_blob_data #:nodoc:
129
- return if @blob_data
130
-
131
- @blob_data = self.class.read_blob_data(self.name)
132
-
133
- # reset depending instance variables
134
- @mandatory_custom_attributes = @mandatory_attributes = nil
135
- end
136
-
137
- def build_mandatory_attribute_arrays #:nodoc:
138
- return if @mandatory_attributes
139
-
140
- load_blob_data
141
-
142
- @mandatory_custom_attributes = []
143
- @mandatory_attributes = []
144
- (@blob_data['mandatoryAttributes'] || []).each do |attr|
145
- attr_name = attr.to_s
146
- if self.custom_attribute?(attr_name)
147
- @mandatory_custom_attributes << attr_name
148
- else
149
- # only modify built-in attributes; i.e. `validFrom` will become `valid_from`
150
- attr_name = attr_name.underscore
151
- end
152
- @mandatory_attributes << attr_name
153
- end
154
- end
155
-
156
- end
157
-
158
- end
@@ -1,5 +0,0 @@
1
- module RailsConnector
2
- class ObjClassAttr < RailsConnector::AbstractModel
3
- has_many :custom_attributes_raw, :class_name => '::RailsConnector::Attribute', :foreign_key => 'attribute_id', :primary_key => 'attribute_id'
4
- end
5
- end
@@ -1,18 +0,0 @@
1
- # -*- encoding : utf-8 -*-
2
- module RailsConnector
3
-
4
- # This class allows us to read out the version and
5
- # the reminder information of an Obj
6
- class ObjectWithMetaData < RailsConnector::AbstractModel #:nodoc:
7
-
8
- # If we name the class Object, conflicts with the plain Ruby
9
- # objects inside the RailsConnector will occur.
10
- def self.table_name
11
- "#{table_name_prefix}" "objects"
12
- end
13
-
14
- self.primary_key = :object_id
15
-
16
- end
17
-
18
- end
@@ -1,91 +0,0 @@
1
- # -*- encoding : utf-8 -*-
2
- require 'singleton'
3
- require 'set'
4
-
5
- module RailsConnector
6
- module Meta
7
- class EagerLoader
8
- include Singleton
9
- attr_reader :obj_classes
10
-
11
- def initialize
12
- # Rails.logger.debug "EagerLoader: I am eager to start working"
13
- @obj_classes = {}
14
- # Rails 3.1 contains a bug that screws attribute loading
15
- # attributes are set to assigned classes
16
- if ::Rails::VERSION::MAJOR == 3 && ::Rails::VERSION::MINOR == 1
17
- RailsConnector::ObjClass.all.each do |obj_class|
18
- obj_class.custom_attributes
19
- @obj_classes[obj_class.name] = obj_class
20
- end
21
- else
22
- RailsConnector::ObjClass.includes(:custom_attributes_raw).all.each do |obj_class|
23
- @obj_classes[obj_class.name] = obj_class
24
- end
25
- preload_attribute_blobs
26
- end
27
- end
28
-
29
- def obj_class(name)
30
- name = name.to_s
31
- if !@obj_classes.fetch(name, nil).nil?
32
- @obj_classes[name]
33
- else
34
- # TODO: preload_attribute_blobs for obj_class
35
- @obj_classes[name] ||= RailsConnector::ObjClass.find_by_obj_class_name(name)
36
- end
37
- end
38
-
39
- def forget_obj_class(name)
40
- @obj_classes.delete(name.to_s)
41
- end
42
-
43
- protected
44
- def preload_attribute_blobs
45
- attribute_names = Set.new
46
- @obj_classes.each do |_, obj_class|
47
- obj_class.custom_attributes.each do |attribute_name, _|
48
- attribute_names << attribute_name
49
- end
50
- end
51
-
52
- blob_names = attribute_names.map {|attribute_name| "#{attribute_name}.jsonAttributeDict" }
53
- # Fiona >= 6.8
54
- if RailsConnector::BlobMapping.exists?
55
- blob_names = attribute_names.map {|attribute_name| "#{attribute_name}.jsonAttributeDict" }
56
- fingerprint_map = RailsConnector::BlobMapping.get_fingerprint_map(blob_names)
57
- blob_fingerprints = fingerprint_map.values
58
- # NOTE: this is correct!
59
- blobs = RailsConnector::Blob.where(:blob_name => blob_fingerprints).to_a
60
- blob_map = Hash[blobs.map {|b| [b.blob_name, b]}]
61
-
62
- @obj_classes.each do |_, obj_class|
63
- obj_class.custom_attributes.each do |_, attribute|
64
- blob_name = "#{attribute.name}.jsonAttributeDict"
65
- fingerprint = fingerprint_map[blob_name]
66
- blob = blob_map[fingerprint]
67
-
68
- next unless blob && blob.blob_data?
69
- attribute.instance_variable_set(:@blob_data, ::JSON.parse(blob.blob_data))
70
- end
71
- end
72
- # Fiona = 6.7
73
- else
74
- blob_names = attribute_names.map {|attribute_name| "#{attribute_name}.jsonAttributeDict" }
75
- blobs = RailsConnector::Blob.where(:blob_name => blob_names).to_a
76
- blob_map = Hash[blobs.map {|b| [b.blob_name, b]}]
77
-
78
- @obj_classes.each do |_, obj_class|
79
- obj_class.custom_attributes.each do |_, attribute|
80
- blob_name = "#{attribute.name}.jsonAttributeDict"
81
- blob = blob_map[blob_name]
82
-
83
- next unless blob && blob.blob_data?
84
- attribute.instance_variable_set(:@blob_data, ::JSON.parse(blob.blob_data))
85
- end
86
- end
87
- end
88
- end
89
- end
90
- end
91
- end