hydra_attribute 0.4.2 → 0.5.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. data/.gitignore +2 -1
  2. data/.travis.yml +6 -5
  3. data/CHANGELOG.md +6 -0
  4. data/Gemfile +1 -1
  5. data/README.md +3 -3
  6. data/Rakefile +2 -7
  7. data/gemfiles/activerecord-3.2.gemfile +5 -0
  8. data/hydra_attribute.gemspec +6 -7
  9. data/lib/hydra_attribute.rb +17 -18
  10. data/lib/hydra_attribute/active_record.rb +34 -13
  11. data/lib/hydra_attribute/active_record/association_preloader.rb +47 -28
  12. data/lib/hydra_attribute/active_record/attribute_methods.rb +29 -140
  13. data/lib/hydra_attribute/active_record/mass_assignment_security.rb +39 -0
  14. data/lib/hydra_attribute/active_record/migration.rb +4 -4
  15. data/lib/hydra_attribute/active_record/relation.rb +6 -7
  16. data/lib/hydra_attribute/active_record/relation/query_methods.rb +28 -18
  17. data/lib/hydra_attribute/hydra_attribute.rb +12 -49
  18. data/lib/hydra_attribute/hydra_attribute_set.rb +67 -0
  19. data/lib/hydra_attribute/hydra_entity.rb +110 -0
  20. data/lib/hydra_attribute/hydra_entity_attribute_association.rb +155 -0
  21. data/lib/hydra_attribute/hydra_set.rb +24 -26
  22. data/lib/hydra_attribute/hydra_value.rb +210 -0
  23. data/lib/hydra_attribute/identity_map.rb +18 -0
  24. data/lib/hydra_attribute/middleware/identity_map.rb +15 -0
  25. data/lib/hydra_attribute/migrator.rb +24 -21
  26. data/lib/hydra_attribute/model.rb +47 -0
  27. data/lib/hydra_attribute/model/cacheable.rb +207 -0
  28. data/lib/hydra_attribute/model/dirty.rb +39 -0
  29. data/lib/hydra_attribute/model/has_many_through.rb +168 -0
  30. data/lib/hydra_attribute/model/identity_map.rb +59 -0
  31. data/lib/hydra_attribute/model/mediator.rb +89 -0
  32. data/lib/hydra_attribute/model/notifiable.rb +23 -0
  33. data/lib/hydra_attribute/model/persistence.rb +424 -0
  34. data/lib/hydra_attribute/model/validations.rb +40 -0
  35. data/lib/hydra_attribute/version.rb +1 -1
  36. data/spec/environments/mysql.rb +23 -0
  37. data/spec/environments/postgresql.rb +23 -0
  38. data/spec/environments/sqlite.rb +12 -0
  39. data/spec/fixtures/category.rb +8 -0
  40. data/spec/fixtures/product.rb +8 -0
  41. data/spec/fixtures/product_black_list.rb +13 -0
  42. data/spec/fixtures/product_white_list.rb +13 -0
  43. data/spec/hydra_attribute/active_record/attribute_methods_spec.rb +23 -28
  44. data/spec/hydra_attribute/active_record/mass_assignment_security_spec.rb +41 -0
  45. data/spec/hydra_attribute/active_record_spec.rb +577 -0
  46. data/spec/hydra_attribute/hydra_attribute_set_spec.rb +651 -0
  47. data/spec/hydra_attribute/hydra_attribute_spec.rb +208 -10
  48. data/spec/hydra_attribute/hydra_entity_attribute_association_spec.rb +216 -0
  49. data/spec/hydra_attribute/hydra_entity_spec.rb +71 -0
  50. data/spec/hydra_attribute/hydra_set_spec.rb +51 -10
  51. data/spec/hydra_attribute/hydra_value_spec.rb +286 -0
  52. data/spec/hydra_attribute/identity_map_spec.rb +47 -0
  53. data/spec/hydra_attribute/migrator_spec.rb +411 -0
  54. data/spec/hydra_attribute/model/cacheable_spec.rb +106 -0
  55. data/spec/hydra_attribute/model/has_many_through_spec.rb +132 -0
  56. data/spec/hydra_attribute/model/identity_map_spec.rb +39 -0
  57. data/spec/hydra_attribute/model/mediator_spec.rb +62 -0
  58. data/spec/hydra_attribute/model/persistence_spec.rb +550 -0
  59. data/spec/hydra_attribute/model_spec.rb +39 -0
  60. data/spec/hydra_attribute_spec.rb +36 -0
  61. data/spec/spec_helper.rb +10 -42
  62. metadata +76 -100
  63. data/Appraisals +0 -7
  64. data/cucumber.yml +0 -1
  65. data/features/entity/create.feature +0 -145
  66. data/features/entity/destroy.feature +0 -111
  67. data/features/entity/new.feature +0 -121
  68. data/features/entity/update.feature +0 -147
  69. data/features/hydra_attribute/create.feature +0 -30
  70. data/features/hydra_attribute/destroy.feature +0 -26
  71. data/features/hydra_attribute/update.feature +0 -36
  72. data/features/hydra_set/destroy.feature +0 -31
  73. data/features/migrations/create_and_drop.feature +0 -165
  74. data/features/migrations/migrate_and_rollback.feature +0 -211
  75. data/features/relation/query_methods/group.feature +0 -42
  76. data/features/relation/query_methods/order.feature +0 -67
  77. data/features/relation/query_methods/reorder.feature +0 -29
  78. data/features/relation/query_methods/reverse_order.feature +0 -29
  79. data/features/relation/query_methods/select.feature +0 -50
  80. data/features/relation/query_methods/where.feature +0 -115
  81. data/features/step_definitions/connections.rb +0 -65
  82. data/features/step_definitions/model_steps.rb +0 -136
  83. data/features/step_definitions/query_methods.rb +0 -48
  84. data/features/step_definitions/record_steps.rb +0 -93
  85. data/features/support/env.rb +0 -38
  86. data/features/support/world.rb +0 -61
  87. data/lib/hydra_attribute/active_record/association.rb +0 -113
  88. data/lib/hydra_attribute/active_record/reflection.rb +0 -16
  89. data/lib/hydra_attribute/association_builder.rb +0 -69
  90. data/lib/hydra_attribute/builder.rb +0 -37
  91. data/lib/hydra_attribute/entity_callbacks.rb +0 -26
  92. data/lib/hydra_attribute/hydra_attribute_methods.rb +0 -226
  93. data/lib/hydra_attribute/hydra_methods.rb +0 -528
  94. data/lib/hydra_attribute/hydra_set_methods.rb +0 -95
  95. data/lib/hydra_attribute/hydra_value_methods.rb +0 -21
  96. data/lib/hydra_attribute/memoizable.rb +0 -37
  97. data/spec/hydra_attribute/active_record/relation/query_methods_spec.rb +0 -31
  98. data/spec/hydra_attribute/hydra_attribute_methods_spec.rb +0 -458
  99. data/spec/hydra_attribute/hydra_methods_spec.rb +0 -456
  100. data/spec/hydra_attribute/hydra_set_methods_spec.rb +0 -203
  101. data/spec/hydra_attribute/memoizable_spec.rb +0 -95
@@ -1,37 +0,0 @@
1
- module HydraAttribute
2
- class Builder
3
- attr_reader :klass
4
-
5
- def initialize(klass)
6
- [
7
- ActiveRecord::Scoping,
8
- ActiveRecord::AttributeMethods,
9
- EntityCallbacks
10
- ].each do |m|
11
- klass.send :include, m
12
- end
13
-
14
- @klass = klass
15
- end
16
-
17
- def self.build(klass)
18
- new(klass).build
19
- end
20
-
21
- def build
22
- build_associations
23
- update_mass_assignment_security
24
- end
25
-
26
- private
27
- def build_associations
28
- SUPPORTED_BACKEND_TYPES.each do |type|
29
- AssociationBuilder.build(klass, type)
30
- end
31
- end
32
-
33
- def update_mass_assignment_security
34
- klass.hydra_attributes.each(&:update_mass_assignment_security)
35
- end
36
- end
37
- end
@@ -1,26 +0,0 @@
1
- module HydraAttribute
2
- module EntityCallbacks
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- after_create :save_hydra_values
7
- after_update :save_hydra_values
8
- before_destroy :destroy_hydra_values
9
- end
10
-
11
- private
12
- def save_hydra_values
13
- changed = false
14
- self.class.hydra_set_attribute_backend_types(hydra_set_id).each do |backend_type|
15
- changed = true if hydra_value_association(backend_type).save
16
- end
17
- touch if changed
18
- end
19
-
20
- def destroy_hydra_values
21
- self.class.hydra_attribute_backend_types.each do |backend_type|
22
- AssociationBuilder.class_name(self.class, backend_type).constantize.where(entity_id: id).delete_all
23
- end
24
- end
25
- end
26
- end
@@ -1,226 +0,0 @@
1
- module HydraAttribute
2
-
3
- # @see HydraAttribute::HydraAttributeMethods::ClassMethods ClassMethods for documentation.
4
- module HydraAttributeMethods
5
- extend ActiveSupport::Concern
6
-
7
- module ClassMethods
8
- extend Memoizable
9
-
10
- # Returns prepared +ActiveRecord::Relation+ object with preloaded attributes for current entity.
11
- #
12
- # @note This method is cacheable, so just one request per entity will be sent to the database.
13
- # @example
14
- # Product.hydra_attributes # ActiveRecord::Relation
15
- # Product.hydra_attributes.map(&:name) # ["title", "color", ...]
16
- # Product.hydra_attributes.create(name: 'title', backend_type: 'string') # Create and return new attribute
17
- # Product.hydra_attributes.each(&:destroy) # Remove all attributes
18
- # @return [ActiveRecord::Relation] contains attributes for current entity
19
- def hydra_attributes
20
- HydraAttribute.where(entity_type: base_class.model_name)
21
- end
22
- hydra_memoize :hydra_attributes
23
-
24
- # Finds <tt>HydraAttribute::HydraAttribute</tt> model by +id+ or +name+. Returns +nil+ for unknown attribute.
25
- #
26
- # @note This method is cacheable per +identifier+. It's better to use it instead of manually searching from <tt>hydra_attributes</tt> collection.
27
- # @example
28
- # Product.hydra_attribute('name') # HydraAttribute::HydraAttribute
29
- # Product.hydra_attribute('name') # Returns HydraAttribute::HydraAttribute from cache
30
- # Product.hydra_attribute(10) # HydraAttribute::HydraAttribute
31
- # Product.hydra_attribute('FAKE') # nil
32
- #
33
- # # It's better to use this method
34
- # Product.hydra_attribute('name')
35
- # # instead of manually searching
36
- # Product.hydra_attributes.detect { |attr| attr.name == 'name' || attr.id == 'id' }
37
- # @param identifier [String, Integer] accepts attribute name or id
38
- # @return [HydraAttribute::HydraAttribute, NilClass] attribute model or nil if wasn't found
39
- def hydra_attribute(identifier)
40
- hydra_attributes.find do |hydra_attribute|
41
- hydra_attribute.id == identifier || hydra_attribute.name == identifier
42
- end
43
- end
44
- hydra_memoize :hydra_attribute
45
-
46
- # Returns unique array of attribute backend types.
47
- #
48
- # @note This method is cacheable therefore, the definition of values is carried out only once.
49
- # @example
50
- # Product.hydra_attributes.create(name: 'one', backend_type: 'string')
51
- # Product.hydra_attributes.create(name: 'two', backend_type: 'string')
52
- # Product.hydra_attributes.create(name: 'three', backend_type: 'integer')
53
- #
54
- # Product.hydra_attribute_backend_types # ["string", "integer"]
55
- # @return [Array<String>}] contains backend types
56
- def hydra_attribute_backend_types
57
- hydra_attributes.map(&:backend_type).uniq
58
- end
59
- hydra_memoize :hydra_attribute_backend_types
60
-
61
- # @!method hydra_attribute_ids
62
- # Returns array of attribute ids.
63
- #
64
- # @note This method is cacheable therefore, the definition of values is carried out only once.
65
- # @example
66
- # Product.hydra_attributes.create(name: 'one', backend_type: 'string') # 1
67
- # Product.hydra_attributes.create(name: 'two', backend_type: 'string') # 2
68
- # Product.hydra_attributes.create(name: 'three', backend_type: 'integer') # 3
69
- #
70
- # Product.hydra_attribute_ids # [1, 2, 3]
71
- # @return [Array<Fixnum>] contains attribute ids
72
-
73
- ##
74
- # @!method hydra_attribute_names
75
- # Returns array of attribute names.
76
- #
77
- # @note This method is cacheable therefore, the definition of values is carried out only once.
78
- # @example
79
- # Product.hydra_attributes.create(name: 'one', backend_type: 'string')
80
- # Product.hydra_attributes.create(name: 'two', backend_type: 'string')
81
- # Product.hydra_attributes.create(name: 'three', backend_type: 'integer')
82
- #
83
- # Product.hydra_attribute_names # ["one", "two", "three"]
84
- # @return [Array<String>] contains attribute names
85
- %w(id name).each do |prefix|
86
- module_eval <<-EOS, __FILE__, __LINE__ + 1
87
- def hydra_attribute_#{prefix}s
88
- hydra_attributes.map(&:#{prefix})
89
- end
90
- hydra_memoize :hydra_attribute_#{prefix}s
91
- EOS
92
- end
93
-
94
- # Groups current attributes by backend type.
95
- #
96
- # @note This method is cacheable therefore, the group operation is carried out only once.
97
- # @example
98
- # Product.hydra_attributes_by_backend_type
99
- # # {"string" => [...], "integer" => [...]}
100
- # @return [Hash{String => Array<HydraAttribute::HydraAttribute>}] contains grouped attribute models by backend type
101
- def hydra_attributes_by_backend_type
102
- hydra_attributes.group_by(&:backend_type)
103
- end
104
- hydra_memoize :hydra_attributes_by_backend_type
105
-
106
- # @!method hydra_attribute_ids_by_backend_type
107
- # Group attribute ids by backend type.
108
- #
109
- # @note This method is cacheable therefore, the group operation is carried out only once.
110
- # @example
111
- # Product.hydra_attributes.create(name: 'one', backend_type: 'string') # 1
112
- # Product.hydra_attributes.create(name: 'two', backend_type: 'string') # 2
113
- # Product.hydra_attributes.create(name: 'three', backend_type: 'integer') # 3
114
- #
115
- # Product.hydra_attribute_ids_by_backend_type
116
- # # {"string" => [1, 2], "integer" => [3]}
117
- # @return [Hash{String => Array<Fixnum>}] contains grouped attribute ids by backend type
118
-
119
- # @!method hydra_attribute_names_by_backend_type
120
- # Group attribute names by backend type.
121
- #
122
- # @note This method is cacheable therefore, the group operation is carried out only once.
123
- # @example
124
- # Product.hydra_attributes.create(name: 'one', backend_type: 'string')
125
- # Product.hydra_attributes.create(name: 'two', backend_type: 'string')
126
- # Product.hydra_attributes.create(name: 'three', backend_type: 'integer')
127
- #
128
- # Product.hydra_attribute_names_by_backend_type
129
- # # {"string" => ["one", "two"], "integer" => ["three"]}
130
- # @return [Hash{String => Array<String>}] contains grouped attribute names by backend type
131
- %w(id name).each do |prefix|
132
- module_eval <<-EOS, __FILE__, __LINE__ + 1
133
- def hydra_attribute_#{prefix}s_by_backend_type
134
- hydra_attributes.each_with_object({}) do |hydra_attribute, object|
135
- object[hydra_attribute.backend_type] ||= []
136
- object[hydra_attribute.backend_type] << hydra_attribute.#{prefix}
137
- end
138
- end
139
- hydra_memoize :hydra_attribute_#{prefix}s_by_backend_type
140
- EOS
141
- end
142
-
143
- # Returns array of attributes for passed backend type.
144
- #
145
- # @note If no attributes, returns blank array.
146
- # @example
147
- # Product.hydra_attributes.create(name: 'one', backend_type: 'string')
148
- # Product.hydra_attributes.create(name: 'two', backend_type: 'string')
149
- # Product.hydra_attributes.create(name: 'three', backend_type: 'integer')
150
- #
151
- # Product.hydra_attributes_for_backend_type('string')
152
- # # [<HydraAttribute::HydraAttribute id: 1, name: "one", ...>, <HydraAttribute::HydraAttribute id: 2, name: "two", ...>]
153
- #
154
- # Product.hydra_attributes_for_backend_type('float') # []
155
- # @param backend_type [String] backend type of attributes
156
- # @return [Array<HydraAttribute::HydraAttribute>] contains attribute models for passed backend type
157
- def hydra_attributes_for_backend_type(backend_type)
158
- hydra_attributes = hydra_attributes_by_backend_type[backend_type]
159
- hydra_attributes.nil? ? [] : hydra_attributes
160
- end
161
-
162
- # @!method hydra_attribute_ids_for_backend_type(backend_type)
163
- # Returns array of attribute ids for passed backend type.
164
- #
165
- # @note If no attributes, returns blank array.
166
- # @example
167
- # Product.hydra_attributes.create(name: 'one', backend_type: 'string') # 1
168
- # Product.hydra_attributes.create(name: 'two', backend_type: 'string') # 2
169
- # Product.hydra_attributes.create(name: 'three', backend_type: 'integer') # 3
170
- #
171
- # Product.hydra_attributes_for_backend_type('string') # [1, 2]
172
- # Product.hydra_attributes_for_backend_type('float') # []
173
- # @param backend_type [String] backend type of attributes
174
- # @return [Array<Fixnum>] contains attribute ids for passed backend type
175
-
176
- # @!method hydra_attribute_names_for_backend_type(backend_type)
177
- # Returns array of attribute names for passed backend type.
178
- #
179
- # @note If no attributes, returns blank array.
180
- # @example
181
- # Product.hydra_attributes.create(name: 'one', backend_type: 'string')
182
- # Product.hydra_attributes.create(name: 'two', backend_type: 'string')
183
- # Product.hydra_attributes.create(name: 'three', backend_type: 'integer')
184
- #
185
- # Product.hydra_attributes_for_backend_type('string') # ["one", "two"]
186
- # Product.hydra_attributes_for_backend_type('float') # []
187
- # @param backend_type [String] backend type of attributes
188
- # @return [Array<HydraAttribute::HydraAttribute>] contains attribute models for passed backend type
189
- %w(id name).each do |prefix|
190
- module_eval <<-EOS, __FILE__, __LINE__ + 1
191
- def hydra_attribute_#{prefix}s_for_backend_type(backend_type)
192
- values = hydra_attribute_#{prefix}s_by_backend_type[backend_type]
193
- values.nil? ? [] : values
194
- end
195
- EOS
196
- end
197
-
198
- # Clear cache for the following methods:
199
- # * hydra_attributes
200
- # * hydra_attribute(identifier)
201
- # * hydra_attribute_ids
202
- # * hydra_attribute_names
203
- # * hydra_attribute_backend_types
204
- # * hydra_attributes_by_backend_type
205
- # * hydra_attribute_ids_by_backend_type
206
- # * hydra_attribute_names_by_backend_type
207
- #
208
- # @note This method should not be called manually. It used for hydra_attribute gem engine.
209
- # @return [NilClass]
210
- def clear_hydra_attribute_cache!
211
- [
212
- :@hydra_attributes,
213
- :@hydra_attribute,
214
- :@hydra_attribute_ids,
215
- :@hydra_attribute_names,
216
- :@hydra_attribute_backend_types,
217
- :@hydra_attributes_by_backend_type,
218
- :@hydra_attribute_ids_by_backend_type,
219
- :@hydra_attribute_names_by_backend_type,
220
- ].each do |variable|
221
- remove_instance_variable(variable) if instance_variable_defined?(variable)
222
- end
223
- end
224
- end
225
- end
226
- end
@@ -1,528 +0,0 @@
1
- module HydraAttribute
2
-
3
- # @see HydraAttribute::HydraMethods::ClassMethods ClassMethods for additional documentation
4
- module HydraMethods
5
- extend ActiveSupport::Concern
6
- extend Memoizable
7
-
8
- include HydraSetMethods
9
- include HydraAttributeMethods
10
- include HydraValueMethods
11
-
12
- included do
13
- alias_method_chain :write_attribute, :hydra_set_id
14
- end
15
-
16
- module ClassMethods
17
- extend Memoizable
18
-
19
- # Finds attribute for attribute sets. Returns all attributes if attribute set is undefined.
20
- #
21
- # @example attribute set exists
22
- # Product.hydra_attributes.create(name: 'name', backend_type: 'string')
23
- #
24
- # hydra_set = Product.hydra_sets.create(name: 'Default')
25
- # hydra_set.hydra_attributes.create(name: 'title', backend_type: 'string')
26
- # hydra_set.hydra_attributes.create(name: 'color', backend_type: 'string')
27
- #
28
- # Product.hydra_set_attributes('Default')
29
- # # [<HydraAttribute::HydraAttribute name: "title">, <HydraAttribute::HydraAttribute name: "color">]
30
- #
31
- # @example attribute set doesn't exist
32
- # Product.hydra_attributes.create(name: 'name', backend_type: 'string')
33
- #
34
- # hydra_set = Product.hydra_sets.create(name: 'Default')
35
- # hydra_set.hydra_attributes.create(name: 'title', backend_type: 'string')
36
- #
37
- # Product.hydra_set_attributes('FAKE')
38
- # # [<HydraAttribute::HydraAttribute name: "name">, <HydraAttribute::HydraAttribute name: "title">]
39
- #
40
- # @param hydra_set_identifier [Fixnum, String] id or name of attribute set
41
- # @return [ActiveRecord::Relation] contains preloaded attribute models
42
- def hydra_set_attributes(hydra_set_identifier)
43
- hydra_set = hydra_set(hydra_set_identifier)
44
- hydra_set.nil? ? hydra_attributes : hydra_set.hydra_attributes
45
- end
46
-
47
- # Returns backend types for attributes which are assigned to passed attribute set.
48
- # If attribute set doesn't exist, return all attribute backend types.
49
- #
50
- # @note This method is cacheable
51
- #
52
- # @example attribute set exists
53
- # Product.hydra_attributes.create(name: 'name', backend_type: 'string')
54
- #
55
- # hydra_set = Product.hydra_sets.create(name: 'Default')
56
- # hydra_set.hydra_attributes.create(name: 'price', backend_type: 'float')
57
- # hydra_set.hydra_attributes.create(name: 'active', backend_type: 'boolean')
58
- #
59
- # Product.hydra_set_attribute_backend_types('Default')
60
- # # ["float", "boolean"]
61
- #
62
- # @example attribute set doesn't exist
63
- # Product.hydra_attributes.create(name: 'name', backend_type: 'string')
64
- #
65
- # hydra_set = Product.hydra_sets.create(name: 'Default')
66
- # hydra_set.hydra_attributes.create(name: 'price', backend_type: 'float')
67
- # hydra_set.hydra_attributes.create(name: 'active', backend_type: 'boolean')
68
- #
69
- # Product.hydra_set_attribute_backend_types('FAKE')
70
- # # ["string", float", "boolean"]
71
- #
72
- # @param hydra_set_identifier [Fixnum, String] id or name of attribute set
73
- # @return [Array<String>] contains unique list of attribute backend types
74
- def hydra_set_attribute_backend_types(hydra_set_identifier)
75
- hydra_set_attributes(hydra_set_identifier).map(&:backend_type).uniq
76
- end
77
- hydra_memoize :hydra_set_attribute_backend_types
78
-
79
- # @!method hydra_set_attribute_ids(hydra_set_identifier)
80
- # Returns ids for attributes which are assigned to passed attribute set.
81
- # If attribute set doesn't exist, return all attribute ids.
82
- #
83
- # @note This method is cacheable
84
- #
85
- # @example attribute set exists
86
- # Product.hydra_attributes.create(name: 'name', backend_type: 'string') # 1
87
- #
88
- # hydra_set = Product.hydra_sets.create(name: 'Default')
89
- # hydra_set.hydra_attributes.create(name: 'price', backend_type: 'float') # 2
90
- # hydra_set.hydra_attributes.create(name: 'active', backend_type: 'boolean') # 3
91
- #
92
- # Product.hydra_set_attribute_ids('Default')
93
- # # [2, 3]
94
- #
95
- # @example attribute set doesn't exist
96
- # Product.hydra_attributes.create(name: 'name', backend_type: 'string') # 1
97
- #
98
- # hydra_set = Product.hydra_sets.create(name: 'Default')
99
- # hydra_set.hydra_attributes.create(name: 'price', backend_type: 'float') # 2
100
- # hydra_set.hydra_attributes.create(name: 'active', backend_type: 'boolean') # 3
101
- #
102
- # Product.hydra_set_attribute_ids('FAKE')
103
- # # [1, 2, 3]
104
- #
105
- # @param hydra_set_identifier [Fixnum, String] id or name of attribute set
106
- # @return [Array<Fixnum>] contains unique list of attribute ids
107
-
108
- # @!method hydra_set_attribute_names(hydra_set_identifier)
109
- # Returns names for attributes which are assigned to passed attribute set.
110
- # If attribute set doesn't exist, return all attribute names.
111
- #
112
- # @note This method is cacheable
113
- #
114
- # @example attribute set exists
115
- # Product.hydra_attributes.create(name: 'name', backend_type: 'string')
116
- #
117
- # hydra_set = Product.hydra_sets.create(name: 'Default')
118
- # hydra_set.hydra_attributes.create(name: 'price', backend_type: 'float')
119
- # hydra_set.hydra_attributes.create(name: 'active', backend_type: 'boolean')
120
- #
121
- # Product.hydra_set_attribute_names('Default')
122
- # # ["price", "active"]
123
- #
124
- # @example attribute set doesn't exist
125
- # Product.hydra_attributes.create(name: 'name', backend_type: 'string')
126
- #
127
- # hydra_set = Product.hydra_sets.create(name: 'Default')
128
- # hydra_set.hydra_attributes.create(name: 'price', backend_type: 'float')
129
- # hydra_set.hydra_attributes.create(name: 'active', backend_type: 'boolean')
130
- #
131
- # Product.hydra_set_attribute_names('FAKE')
132
- # # ["name", "price", "active"]
133
- #
134
- # @param hydra_set_identifier [Fixnum, String] id or name of attribute set
135
- # @return [Array<String>] contains unique list of attribute names
136
- %w(id name).each do |prefix|
137
- module_eval <<-EOS, __FILE__, __LINE__ + 1
138
- def hydra_set_attribute_#{prefix}s(hydra_set_identifier)
139
- hydra_set_attributes(hydra_set_identifier).map(&:#{prefix})
140
- end
141
- hydra_memoize :hydra_set_attribute_#{prefix}s
142
- EOS
143
- end
144
-
145
- # Groups attributes for attribute set by backend type.
146
- # If attribute set doesn't exist, group all attributes.
147
- #
148
- # @note This method is cacheable
149
- #
150
- # @example attribute set exists
151
- # Product.hydra_attributes.create(name: 'name', backend_type: 'string')
152
- #
153
- # hydra_set = Product.hydra_sets.create(name: 'Default')
154
- # hydra_set.hydra_attributes.create(name: 'price', backend_type: 'float')
155
- # hydra_set.hydra_attributes.create(name: 'active', backend_type: 'boolean')
156
- #
157
- # Product.hydra_set_attributes_by_backend_type('Default')
158
- # # {
159
- # # "float"=>[<HydraAttribute::HydraAttribute name: 'price'>],
160
- # # "boolean"=>[<HydraAttribute::HydraAttribute name: 'active'>]
161
- # # }
162
- #
163
- # @example attribute set doesn't exist
164
- # Product.hydra_attributes.create(name: 'name', backend_type: 'string')
165
- #
166
- # hydra_set = Product.hydra_sets.create(name: 'Default')
167
- # hydra_set.hydra_attributes.create(name: 'price', backend_type: 'float')
168
- # hydra_set.hydra_attributes.create(name: 'active', backend_type: 'boolean')
169
- #
170
- # Product.hydra_set_attributes_by_backend_type('FAKE')
171
- # # {
172
- # # "string"=>[<HydraAttribute::HydraAttribute name: 'name'>],
173
- # # "float"=>[<HydraAttribute::HydraAttribute name: 'price'>],
174
- # # "boolean"=>[<HydraAttribute::HydraAttribute name: 'active'>]
175
- # # }
176
- #
177
- # @param hydra_set_identifier [Fixnum, String] id or name of attribute set
178
- # @return [Hash{String => Array<HydraAttribute::HydraAttribute>}] contains grouped attributes by their backend types
179
- def hydra_set_attributes_by_backend_type(hydra_set_identifier)
180
- hydra_set_attributes(hydra_set_identifier).group_by(&:backend_type)
181
- end
182
- hydra_memoize :hydra_set_attributes_by_backend_type
183
-
184
- # @!method hydra_set_attribute_ids_by_backend_type(hydra_set_identifier)
185
- # Groups attribute ids for attribute set by backend type.
186
- # If attribute set doesn't exist, group all attribute ids.
187
- #
188
- # @note This method is cacheable
189
- #
190
- # @example attribute set exists
191
- # Product.hydra_attributes.create(name: 'name', backend_type: 'string') # 1
192
- #
193
- # hydra_set = Product.hydra_sets.create(name: 'Default')
194
- # hydra_set.hydra_attributes.create(name: 'price', backend_type: 'float') # 2
195
- # hydra_set.hydra_attributes.create(name: 'active', backend_type: 'boolean') # 3
196
- #
197
- # Product.hydra_set_attribute_ids_by_backend_type('Default')
198
- # # {"float"=>[2], "boolean"=>[3]}
199
- #
200
- # @example attribute set doesn't exist
201
- # Product.hydra_attributes.create(name: 'name', backend_type: 'string') # 1
202
- #
203
- # hydra_set = Product.hydra_sets.create(name: 'Default')
204
- # hydra_set.hydra_attributes.create(name: 'price', backend_type: 'float') # 2
205
- # hydra_set.hydra_attributes.create(name: 'active', backend_type: 'boolean') # 3
206
- #
207
- # Product.hydra_set_attribute_ids_by_backend_type('FAKE')
208
- # # {"string"=>[1], "float"=>[2], "boolean"=>[3]}
209
- #
210
- # @param hydra_set_identifier [Fixnum, String] id or name of attribute set
211
- # @return [Hash{String => Array<Fixnum>}] contains grouped attribute ids by their backend types
212
-
213
- # @!method hydra_set_attribute_names_by_backend_type(hydra_set_identifier)
214
- # Groups attribute names for attribute set by backend type.
215
- # If attribute set doesn't exist, group all attribute names.
216
- #
217
- # @note This method is cacheable
218
- #
219
- # @example attribute set exists
220
- # Product.hydra_attributes.create(name: 'name', backend_type: 'string')
221
- #
222
- # hydra_set = Product.hydra_sets.create(name: 'Default')
223
- # hydra_set.hydra_attributes.create(name: 'price', backend_type: 'float')
224
- # hydra_set.hydra_attributes.create(name: 'active', backend_type: 'boolean')
225
- #
226
- # Product.hydra_set_attribute_names_by_backend_type('Default')
227
- # # {"float"=>["price"], "boolean"=>["active"]}
228
- #
229
- # @example attribute set doesn't exist
230
- # Product.hydra_attributes.create(name: 'name', backend_type: 'string')
231
- #
232
- # hydra_set = Product.hydra_sets.create(name: 'Default')
233
- # hydra_set.hydra_attributes.create(name: 'price', backend_type: 'float')
234
- # hydra_set.hydra_attributes.create(name: 'active', backend_type: 'boolean')
235
- #
236
- # Product.hydra_set_attribute_names_by_backend_type('FAKE')
237
- # # {"string"=>["name"], "float"=>["price"], "boolean"=>["active"]}
238
- #
239
- # @param hydra_set_identifier [Fixnum, String] id or name of attribute set
240
- # @return [Hash{String => Array<String>}] contains grouped attribute names by their backend types
241
- %w(id name).each do |prefix|
242
- module_eval <<-EOS, __FILE__, __LINE__ + 1
243
- def hydra_set_attribute_#{prefix}s_by_backend_type(hydra_set_identifier)
244
- hydra_set_attributes(hydra_set_identifier).each_with_object({}) do |hydra_attribute, object|
245
- object[hydra_attribute.backend_type] ||= []
246
- object[hydra_attribute.backend_type] << hydra_attribute.#{prefix}
247
- end
248
- end
249
- hydra_memoize :hydra_set_attribute_#{prefix}s_by_backend_type
250
- EOS
251
- end
252
-
253
- # Returns attributes for attribute set and backend type.
254
- # If attribute set doesn't exist, returns all attributes for backend type.
255
- #
256
- # @example attribute set exists
257
- # Product.hydra_attributes.create(name: 'name', backend_type: 'string')
258
- #
259
- # hydra_set = Product.hydra_sets.create(name: 'Default')
260
- # hydra_sets.hydra_attributes.create(name: 'title', backend_type: 'string')
261
- # hydra_sets.hydra_attributes.create(name: 'price', backend_type: 'float')
262
- #
263
- # Product.hydra_set_attributes_for_backend_type('Default', 'float')
264
- # # [<HydraAttribute::HydraAttribute name: "price">]
265
- #
266
- # @example attribute set doesn't exists
267
- # Product.hydra_attributes.create(name: 'name', backend_type: 'string')
268
- #
269
- # hydra_set = Product.hydra_sets.create(name: 'Default')
270
- # hydra_sets.hydra_attributes.create(name: 'title', backend_type: 'string')
271
- # hydra_sets.hydra_attributes.create(name: 'price', backend_type: 'float')
272
- #
273
- # Product.hydra_set_attributes_for_backend_type('FAKE', 'string')
274
- # # [<HydraAttribute::HydraAttribute name: "name">, <HydraAttribute::HydraAttribute name: "title">]
275
- #
276
- # @example attributes doesn't exist for backend type
277
- # Product.hydra_attributes.create(name: 'name', backend_type: 'string')
278
- #
279
- # hydra_set = Product.hydra_sets.create(name: 'Default')
280
- # hydra_sets.hydra_attributes.create(name: 'title', backend_type: 'string')
281
- # hydra_sets.hydra_attributes.create(name: 'price', backend_type: 'float')
282
- #
283
- # Product.hydra_set_attributes_for_backend_type('Default', 'boolean')
284
- # # []
285
- #
286
- # @param hydra_set_identifier [Fixnum, String] id or name of attribute set
287
- # @param backend_type [String] see HydraAttribute::SUPPORTED_BACKEND_TYPES
288
- # @return [Array] contains attribute models
289
- def hydra_set_attributes_for_backend_type(hydra_set_identifier, backend_type)
290
- hydra_attributes = hydra_set_attributes_by_backend_type(hydra_set_identifier)[backend_type]
291
- hydra_attributes.nil? ? [] : hydra_attributes
292
- end
293
-
294
- # @!method hydra_set_attribute_ids_for_backend_type(hydra_set_identifier, backend_type)
295
- # Returns attribute ids for attribute set and backend type.
296
- # If attribute set doesn't exist, returns all attribute ids for backend type.
297
- #
298
- # @example attribute set exists
299
- # Product.hydra_attributes.create(name: 'name', backend_type: 'string') # 1
300
- #
301
- # hydra_set = Product.hydra_sets.create(name: 'Default')
302
- # hydra_sets.hydra_attributes.create(name: 'title', backend_type: 'string') # 2
303
- # hydra_sets.hydra_attributes.create(name: 'price', backend_type: 'float') # 3
304
- #
305
- # Product.hydra_set_attribute_ids_for_backend_type('Default', 'float') # [2]
306
- #
307
- # @example attribute set doesn't exists
308
- # Product.hydra_attributes.create(name: 'name', backend_type: 'string') # 1
309
- #
310
- # hydra_set = Product.hydra_sets.create(name: 'Default')
311
- # hydra_sets.hydra_attributes.create(name: 'title', backend_type: 'string') # 2
312
- # hydra_sets.hydra_attributes.create(name: 'price', backend_type: 'float') # 3
313
- #
314
- # Product.hydra_set_attribute_ids_for_backend_type('FAKE', 'string') # [1, 2]
315
- #
316
- # @example attributes doesn't exist for backend type
317
- # Product.hydra_attributes.create(name: 'name', backend_type: 'string') # 1
318
- #
319
- # hydra_set = Product.hydra_sets.create(name: 'Default')
320
- # hydra_sets.hydra_attributes.create(name: 'title', backend_type: 'string') # 2
321
- # hydra_sets.hydra_attributes.create(name: 'price', backend_type: 'float') # 3
322
- #
323
- # Product.hydra_set_attribute_ids_for_backend_type('Default', 'boolean') # []
324
- #
325
- # @param hydra_set_identifier [Fixnum, String] id or name of attribute set
326
- # @param backend_type [String] see HydraAttribute::SUPPORTED_BACKEND_TYPES
327
- # @return [Array<Fixnum>] contains attribute ids
328
-
329
- # @!method hydra_set_attribute_names_for_backend_type(hydra_set_identifier, backend_type)
330
- # Returns attribute names for attribute set and backend type.
331
- # If attribute set doesn't exist, returns all attribute names for backend type.
332
- #
333
- # @example attribute set exists
334
- # Product.hydra_attributes.create(name: 'name', backend_type: 'string')
335
- #
336
- # hydra_set = Product.hydra_sets.create(name: 'Default')
337
- # hydra_sets.hydra_attributes.create(name: 'title', backend_type: 'string')
338
- # hydra_sets.hydra_attributes.create(name: 'price', backend_type: 'float')
339
- #
340
- # Product.hydra_set_attribute_names_for_backend_type('Default', 'float') # ["price"]
341
- #
342
- # @example attribute set doesn't exists
343
- # Product.hydra_attributes.create(name: 'name', backend_type: 'string')
344
- #
345
- # hydra_set = Product.hydra_sets.create(name: 'Default')
346
- # hydra_sets.hydra_attributes.create(name: 'title', backend_type: 'string')
347
- # hydra_sets.hydra_attributes.create(name: 'price', backend_type: 'float')
348
- #
349
- # Product.hydra_set_attribute_names_for_backend_type('FAKE', 'string') # ["name", "title"]
350
- #
351
- # @example attributes doesn't exist for backend type
352
- # Product.hydra_attributes.create(name: 'name', backend_type: 'string')
353
- #
354
- # hydra_set = Product.hydra_sets.create(name: 'Default')
355
- # hydra_sets.hydra_attributes.create(name: 'title', backend_type: 'string')
356
- # hydra_sets.hydra_attributes.create(name: 'price', backend_type: 'float')
357
- #
358
- # Product.hydra_set_attribute_names_for_backend_type('Default', 'boolean') # []
359
- #
360
- # @param hydra_set_identifier [Fixnum, String] id or name of attribute set
361
- # @param backend_type [String] see HydraAttribute::SUPPORTED_BACKEND_TYPES
362
- # @return [Array<String>] contains attribute names
363
- %w(id name).each do |prefix|
364
- module_eval <<-EOS, __FILE__, __LINE__ + 1
365
- def hydra_set_attribute_#{prefix}s_for_backend_type(hydra_set_identifier, backend_type)
366
- values = hydra_set_attribute_#{prefix}s_by_backend_type(hydra_set_identifier)[backend_type]
367
- values.nil? ? [] : values
368
- end
369
- EOS
370
- end
371
-
372
- # Clear cache for the following methods:
373
- # * hydra_set_attributes(hydra_set_identifier)
374
- # * hydra_set_attribute_ids(hydra_set_identifier)
375
- # * hydra_set_attribute_names(hydra_set_identifier)
376
- # * hydra_set_attribute_backend_types(hydra_set_identifier)
377
- # * hydra_set_attributes_by_backend_type(hydra_set_identifier)
378
- # * hydra_set_attribute_ids_by_backend_type(hydra_set_identifier)
379
- # * hydra_set_attribute_names_by_backend_type(hydra_set_identifier)
380
- #
381
- # Also calls the following methods:
382
- # * clear_hydra_set_cache!
383
- # * clear_hydra_attribute_cache!
384
- # * clear_hydra_value_cache!
385
- #
386
- # @note This method should not be called manually. It used for hydra_attribute gem engine.
387
- # @return [NilClass]
388
- def clear_hydra_method_cache!
389
- clear_hydra_set_cache!
390
- clear_hydra_attribute_cache!
391
- clear_hydra_value_cache!
392
-
393
- [
394
- :@hydra_set_attributes,
395
- :@hydra_set_attribute_ids,
396
- :@hydra_set_attribute_names,
397
- :@hydra_set_attribute_backend_types,
398
- :@hydra_set_attributes_by_backend_type,
399
- :@hydra_set_attribute_ids_by_backend_type,
400
- :@hydra_set_attribute_names_by_backend_type
401
- ].each do |variable|
402
- remove_instance_variable(variable) if instance_variable_defined?(variable)
403
- end
404
- end
405
- end
406
-
407
- # Returns hash with attribute names and values based on attribute set.
408
- #
409
- # @example
410
- # Product.hydra_attributes.create(name: 'name', backend_type: 'string')
411
- #
412
- # hydra_set = Product.hydra_sets.create(name: 'Default')
413
- # hydra_set.hydra_attributes.create(name: 'title', backend_type: 'string')
414
- # hydra_set.hydra_attributes.create(name: 'color', backend_type: 'string')
415
- #
416
- # product = Product.new
417
- # product.hydra_attributes # {"name"=>nil, "title"=>nil, "color"=>nil}
418
- #
419
- # product.hydra_set_id = hydra_set.id
420
- # product.hydra_attributes # {"title"=>nil, "color"=>nil}
421
- #
422
- # @return [Hash] contains attribute names and values
423
- def hydra_attributes
424
- hydra_value_models.inject({}) do |hydra_attributes, model|
425
- hydra_attributes[model.hydra_attribute_name] = model.value
426
- hydra_attributes
427
- end
428
- end
429
-
430
- # @!method hydra_attribute_ids
431
- # Returns attribute ids
432
- #
433
- # @example
434
- # Product.hydra_attributes.create(name: 'name', backend_type: 'string') # 1
435
- #
436
- # hydra_set = Product.hydra_sets.create(name: 'Default')
437
- # hydra_set.hydra_attributes.create(name: 'title', backend_type: 'string') # 2
438
- # hydra_set.hydra_attributes.create(name: 'color', backend_type: 'string') # 3
439
- #
440
- # product = Product.new
441
- # product.hydra_attribute_ids # [1, 2, 3]
442
- #
443
- # product.hydra_set_id = hydra_set.id
444
- # product.hydra_attribute_ids # [2, 3]
445
- #
446
- # @return [Array] contains attribute ids
447
-
448
- # @!method hydra_attribute_names
449
- # Returns attribute names
450
- #
451
- # @example
452
- # Product.hydra_attributes.create(name: 'name', backend_type: 'string')
453
- #
454
- # hydra_set = Product.hydra_sets.create(name: 'Default')
455
- # hydra_set.hydra_attributes.create(name: 'title', backend_type: 'string')
456
- # hydra_set.hydra_attributes.create(name: 'color', backend_type: 'string')
457
- #
458
- # product = Product.new
459
- # product.hydra_attribute_names # ["name", "title", "color"]
460
- #
461
- # product.hydra_set_id = hydra_set.id
462
- # product.hydra_attribute_names # ["title", "color"]
463
- #
464
- # @return [Array] contains attribute names
465
-
466
- # @!method hydra_attribute_backend_types
467
- # Returns attribute backend types
468
- #
469
- # @example
470
- # Product.hydra_attributes.create(name: 'name', backend_type: 'string')
471
- #
472
- # hydra_set = Product.hydra_sets.create(name: 'Default')
473
- # hydra_set.hydra_attributes.create(name: 'price', backend_type: 'float')
474
- # hydra_set.hydra_attributes.create(name: 'total', backend_type: 'integer')
475
- #
476
- # product = Product.new
477
- # product.hydra_attribute_backend_types # ["string", "float", "integer"]
478
- #
479
- # product.hydra_set_id = hydra_set.id
480
- # product.hydra_attribute_backend_types # ["float", "integer"]
481
- #
482
- # @return [Array] contains attribute backend types
483
- %w(ids names backend_types).each do |prefix|
484
- module_eval <<-EOS, __FILE__, __LINE__ + 1
485
- def hydra_attribute_#{prefix}
486
- self.class.hydra_set_attribute_#{prefix}(hydra_set_id)
487
- end
488
- EOS
489
- end
490
-
491
- # Finds attribute representation as a model by identifier
492
- #
493
- # @note This method is cacheable
494
- # @param identifier [Fixnum, String] id or name of attribute
495
- # @return [ActiveRecord::Base]
496
- def hydra_value_model(identifier)
497
- hydra_attribute = self.class.hydra_attribute(identifier)
498
- if hydra_attribute
499
- association = hydra_value_association(hydra_attribute.backend_type)
500
- association.find_model_or_build(hydra_attribute_id: hydra_attribute.id)
501
- end
502
- end
503
- hydra_memoize :hydra_value_model
504
-
505
- # Returns all attributes as models
506
- #
507
- # @note This method is cacheable
508
- # @return [Array] contains values models
509
- def hydra_value_models
510
- self.class.hydra_set_attribute_backend_types(hydra_set_id).inject([]) do |models, backend_type|
511
- models + hydra_value_association(backend_type).all_models
512
- end
513
- end
514
- hydra_memoize :hydra_value_models
515
-
516
- private
517
- # Resets locked attributes after setting new hydra_set_id
518
- def write_attribute_with_hydra_set_id(attr_name, value)
519
- if attr_name.to_s == 'hydra_set_id'
520
- self.class.hydra_attribute_backend_types.each do |backend_type|
521
- hydra_value_association(backend_type).clear_cache!
522
- end
523
- remove_instance_variable(:@hydra_value_models) if instance_variable_defined?(:@hydra_value_models)
524
- end
525
- write_attribute_without_hydra_set_id(attr_name, value)
526
- end
527
- end
528
- end