hydra_attribute 0.4.2 → 0.5.0.rc1
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/.gitignore +2 -1
- data/.travis.yml +6 -5
- data/CHANGELOG.md +6 -0
- data/Gemfile +1 -1
- data/README.md +3 -3
- data/Rakefile +2 -7
- data/gemfiles/activerecord-3.2.gemfile +5 -0
- data/hydra_attribute.gemspec +6 -7
- data/lib/hydra_attribute.rb +17 -18
- data/lib/hydra_attribute/active_record.rb +34 -13
- data/lib/hydra_attribute/active_record/association_preloader.rb +47 -28
- data/lib/hydra_attribute/active_record/attribute_methods.rb +29 -140
- data/lib/hydra_attribute/active_record/mass_assignment_security.rb +39 -0
- data/lib/hydra_attribute/active_record/migration.rb +4 -4
- data/lib/hydra_attribute/active_record/relation.rb +6 -7
- data/lib/hydra_attribute/active_record/relation/query_methods.rb +28 -18
- data/lib/hydra_attribute/hydra_attribute.rb +12 -49
- data/lib/hydra_attribute/hydra_attribute_set.rb +67 -0
- data/lib/hydra_attribute/hydra_entity.rb +110 -0
- data/lib/hydra_attribute/hydra_entity_attribute_association.rb +155 -0
- data/lib/hydra_attribute/hydra_set.rb +24 -26
- data/lib/hydra_attribute/hydra_value.rb +210 -0
- data/lib/hydra_attribute/identity_map.rb +18 -0
- data/lib/hydra_attribute/middleware/identity_map.rb +15 -0
- data/lib/hydra_attribute/migrator.rb +24 -21
- data/lib/hydra_attribute/model.rb +47 -0
- data/lib/hydra_attribute/model/cacheable.rb +207 -0
- data/lib/hydra_attribute/model/dirty.rb +39 -0
- data/lib/hydra_attribute/model/has_many_through.rb +168 -0
- data/lib/hydra_attribute/model/identity_map.rb +59 -0
- data/lib/hydra_attribute/model/mediator.rb +89 -0
- data/lib/hydra_attribute/model/notifiable.rb +23 -0
- data/lib/hydra_attribute/model/persistence.rb +424 -0
- data/lib/hydra_attribute/model/validations.rb +40 -0
- data/lib/hydra_attribute/version.rb +1 -1
- data/spec/environments/mysql.rb +23 -0
- data/spec/environments/postgresql.rb +23 -0
- data/spec/environments/sqlite.rb +12 -0
- data/spec/fixtures/category.rb +8 -0
- data/spec/fixtures/product.rb +8 -0
- data/spec/fixtures/product_black_list.rb +13 -0
- data/spec/fixtures/product_white_list.rb +13 -0
- data/spec/hydra_attribute/active_record/attribute_methods_spec.rb +23 -28
- data/spec/hydra_attribute/active_record/mass_assignment_security_spec.rb +41 -0
- data/spec/hydra_attribute/active_record_spec.rb +577 -0
- data/spec/hydra_attribute/hydra_attribute_set_spec.rb +651 -0
- data/spec/hydra_attribute/hydra_attribute_spec.rb +208 -10
- data/spec/hydra_attribute/hydra_entity_attribute_association_spec.rb +216 -0
- data/spec/hydra_attribute/hydra_entity_spec.rb +71 -0
- data/spec/hydra_attribute/hydra_set_spec.rb +51 -10
- data/spec/hydra_attribute/hydra_value_spec.rb +286 -0
- data/spec/hydra_attribute/identity_map_spec.rb +47 -0
- data/spec/hydra_attribute/migrator_spec.rb +411 -0
- data/spec/hydra_attribute/model/cacheable_spec.rb +106 -0
- data/spec/hydra_attribute/model/has_many_through_spec.rb +132 -0
- data/spec/hydra_attribute/model/identity_map_spec.rb +39 -0
- data/spec/hydra_attribute/model/mediator_spec.rb +62 -0
- data/spec/hydra_attribute/model/persistence_spec.rb +550 -0
- data/spec/hydra_attribute/model_spec.rb +39 -0
- data/spec/hydra_attribute_spec.rb +36 -0
- data/spec/spec_helper.rb +10 -42
- metadata +76 -100
- data/Appraisals +0 -7
- data/cucumber.yml +0 -1
- data/features/entity/create.feature +0 -145
- data/features/entity/destroy.feature +0 -111
- data/features/entity/new.feature +0 -121
- data/features/entity/update.feature +0 -147
- data/features/hydra_attribute/create.feature +0 -30
- data/features/hydra_attribute/destroy.feature +0 -26
- data/features/hydra_attribute/update.feature +0 -36
- data/features/hydra_set/destroy.feature +0 -31
- data/features/migrations/create_and_drop.feature +0 -165
- data/features/migrations/migrate_and_rollback.feature +0 -211
- data/features/relation/query_methods/group.feature +0 -42
- data/features/relation/query_methods/order.feature +0 -67
- data/features/relation/query_methods/reorder.feature +0 -29
- data/features/relation/query_methods/reverse_order.feature +0 -29
- data/features/relation/query_methods/select.feature +0 -50
- data/features/relation/query_methods/where.feature +0 -115
- data/features/step_definitions/connections.rb +0 -65
- data/features/step_definitions/model_steps.rb +0 -136
- data/features/step_definitions/query_methods.rb +0 -48
- data/features/step_definitions/record_steps.rb +0 -93
- data/features/support/env.rb +0 -38
- data/features/support/world.rb +0 -61
- data/lib/hydra_attribute/active_record/association.rb +0 -113
- data/lib/hydra_attribute/active_record/reflection.rb +0 -16
- data/lib/hydra_attribute/association_builder.rb +0 -69
- data/lib/hydra_attribute/builder.rb +0 -37
- data/lib/hydra_attribute/entity_callbacks.rb +0 -26
- data/lib/hydra_attribute/hydra_attribute_methods.rb +0 -226
- data/lib/hydra_attribute/hydra_methods.rb +0 -528
- data/lib/hydra_attribute/hydra_set_methods.rb +0 -95
- data/lib/hydra_attribute/hydra_value_methods.rb +0 -21
- data/lib/hydra_attribute/memoizable.rb +0 -37
- data/spec/hydra_attribute/active_record/relation/query_methods_spec.rb +0 -31
- data/spec/hydra_attribute/hydra_attribute_methods_spec.rb +0 -458
- data/spec/hydra_attribute/hydra_methods_spec.rb +0 -456
- data/spec/hydra_attribute/hydra_set_methods_spec.rb +0 -203
- data/spec/hydra_attribute/memoizable_spec.rb +0 -95
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
**0.5.0 (...)**
|
|
2
|
+
* Cache all hydra attributes per request
|
|
3
|
+
* Add support of `decimal` backend type
|
|
4
|
+
* Add `id` to `hydra_attribute_sets` table
|
|
5
|
+
* Use new index name pattern `*_idx` instead of `*_index`
|
|
6
|
+
|
|
1
7
|
**0.4.2 (January 20, 2013)**
|
|
2
8
|
* Fixed bug in `count` method which added unnecessary columns to query [#2](https://github.com/kostyantyn/hydra_attribute/issues/2)
|
|
3
9
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# hydra_attribute [](http://badge.fury.io/rb/hydra_attribute) [](http://badge.fury.io/rb/hydra_attribute) [](https://travis-ci.org/kostyantyn/hydra_attribute)
|
|
2
2
|
|
|
3
3
|
[Wiki](https://github.com/kostyantyn/hydra_attribute/wiki) | [RDoc](http://rdoc.info/github/kostyantyn/hydra_attribute)
|
|
4
4
|
|
|
@@ -12,7 +12,7 @@ Until the first major version is released:
|
|
|
12
12
|
|
|
13
13
|
## Requirements
|
|
14
14
|
* ruby >= 1.9.2
|
|
15
|
-
* active_record ~> 3.
|
|
15
|
+
* active_record ~> 3.2
|
|
16
16
|
|
|
17
17
|
## Installation
|
|
18
18
|
|
|
@@ -82,7 +82,7 @@ Creating method accepts the following options:
|
|
|
82
82
|
* **name**. The **required** parameter. Any string is allowed.
|
|
83
83
|
* **backend_type**. The **required** parameter. One of the following strings is allowed: `string`, `text`, `integer`, `float`, `boolean` and `datetime`.
|
|
84
84
|
* **default_value**. The **optional** parameter. Any value is allowed. `nil` is default.
|
|
85
|
-
* **white_list**. The **optional** parameter. Should be `true` or `
|
|
85
|
+
* **white_list**. The **optional** parameter. Should be `true` or `false`. `false` is default. If `white_list: true` is passed, this attribute will be added to white list and will be allowed for mass-assignment. This parameter is in black list for creation by default so if you want to pass it, you have to pass the role `as: :admin` too.
|
|
86
86
|
|
|
87
87
|
```ruby
|
|
88
88
|
Product.hydra_attributes.create({name: 'title', backend_type: 'string', white_list: true}, as: :admin)
|
data/Rakefile
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env rake
|
|
2
2
|
require 'bundler/gem_tasks'
|
|
3
|
-
require 'appraisal'
|
|
4
3
|
require 'rspec/core/rake_task'
|
|
5
|
-
require 'cucumber/rake/task'
|
|
6
4
|
|
|
7
|
-
RSpec::Core::RakeTask.new(
|
|
8
|
-
Cucumber::Rake::Task.new(:features) do |t|
|
|
9
|
-
t.cucumber_opts = '--format pretty'
|
|
10
|
-
end
|
|
5
|
+
RSpec::Core::RakeTask.new(:spec)
|
|
11
6
|
|
|
12
|
-
task default: [:
|
|
7
|
+
task default: [:spec]
|
data/hydra_attribute.gemspec
CHANGED
|
@@ -8,18 +8,17 @@ Gem::Specification.new do |gem|
|
|
|
8
8
|
gem.description = 'hydra_attribute is an implementation of EAV pattern for ActiveRecord models.'
|
|
9
9
|
gem.homepage = 'https://github.com/kostyantyn/hydra_attribute'
|
|
10
10
|
gem.files = `git ls-files`.split("\n")
|
|
11
|
-
gem.test_files = `git ls-files --
|
|
12
|
-
gem.name =
|
|
11
|
+
gem.test_files = `git ls-files -- {spec,features,gemfiles}/*`.split("\n")
|
|
12
|
+
gem.name = 'hydra_attribute'
|
|
13
13
|
gem.require_paths = %w(lib)
|
|
14
14
|
gem.required_ruby_version = Gem::Requirement.new('>= 1.9.2')
|
|
15
15
|
gem.version = HydraAttribute::VERSION
|
|
16
16
|
|
|
17
|
-
gem.add_dependency('activerecord', '~> 3.
|
|
17
|
+
gem.add_dependency('activerecord', '~> 3.2')
|
|
18
18
|
|
|
19
|
-
gem.add_development_dependency('rspec')
|
|
20
|
-
gem.add_development_dependency('cucumber')
|
|
19
|
+
gem.add_development_dependency('rspec', '~> 2.13')
|
|
21
20
|
gem.add_development_dependency('sqlite3')
|
|
22
|
-
gem.add_development_dependency('
|
|
23
|
-
gem.add_development_dependency('
|
|
21
|
+
gem.add_development_dependency('mysql2')
|
|
22
|
+
gem.add_development_dependency('pg')
|
|
24
23
|
gem.add_development_dependency('rake')
|
|
25
24
|
end
|
data/lib/hydra_attribute.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
require 'active_record'
|
|
2
|
+
|
|
1
3
|
module HydraAttribute
|
|
2
|
-
SUPPORTED_BACKEND_TYPES = %w
|
|
4
|
+
SUPPORTED_BACKEND_TYPES = %w[string text integer float decimal boolean datetime].freeze
|
|
3
5
|
|
|
4
6
|
class << self
|
|
5
7
|
def config
|
|
@@ -9,32 +11,29 @@ module HydraAttribute
|
|
|
9
11
|
def setup
|
|
10
12
|
yield config
|
|
11
13
|
end
|
|
14
|
+
|
|
15
|
+
def identity_map
|
|
16
|
+
Thread.current[:hydra_attribute] ||= IdentityMap.new
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def cache(key, value = nil, &block)
|
|
20
|
+
identity_map.cache(key, value, &block)
|
|
21
|
+
end
|
|
12
22
|
end
|
|
13
23
|
|
|
14
24
|
end
|
|
15
25
|
|
|
16
26
|
require 'hydra_attribute/version'
|
|
17
27
|
require 'hydra_attribute/configuration'
|
|
18
|
-
require 'hydra_attribute/association_builder'
|
|
19
|
-
require 'hydra_attribute/builder'
|
|
20
28
|
require 'hydra_attribute/migrator'
|
|
21
|
-
require 'hydra_attribute/
|
|
29
|
+
require 'hydra_attribute/identity_map'
|
|
30
|
+
require 'hydra_attribute/model'
|
|
22
31
|
require 'hydra_attribute/hydra_attribute'
|
|
23
32
|
require 'hydra_attribute/hydra_set'
|
|
24
|
-
require 'hydra_attribute/
|
|
25
|
-
require 'hydra_attribute/
|
|
26
|
-
require 'hydra_attribute/
|
|
27
|
-
require 'hydra_attribute/
|
|
28
|
-
require 'hydra_attribute/hydra_methods'
|
|
33
|
+
require 'hydra_attribute/hydra_attribute_set'
|
|
34
|
+
require 'hydra_attribute/hydra_value'
|
|
35
|
+
require 'hydra_attribute/hydra_entity'
|
|
36
|
+
require 'hydra_attribute/hydra_entity_attribute_association'
|
|
29
37
|
require 'hydra_attribute/active_record'
|
|
30
|
-
require 'hydra_attribute/active_record/scoping'
|
|
31
|
-
require 'hydra_attribute/active_record/reflection'
|
|
32
|
-
require 'hydra_attribute/active_record/association'
|
|
33
|
-
require 'hydra_attribute/active_record/association_preloader'
|
|
34
|
-
require 'hydra_attribute/active_record/migration'
|
|
35
|
-
require 'hydra_attribute/active_record/relation'
|
|
36
|
-
require 'hydra_attribute/active_record/relation/calculations'
|
|
37
|
-
require 'hydra_attribute/active_record/relation/query_methods'
|
|
38
|
-
require 'hydra_attribute/active_record/attribute_methods'
|
|
39
38
|
|
|
40
39
|
require 'hydra_attribute/railtie' if defined?(Rails)
|
|
@@ -1,29 +1,50 @@
|
|
|
1
|
+
require 'hydra_attribute/active_record/attribute_methods'
|
|
2
|
+
require 'hydra_attribute/active_record/migration'
|
|
3
|
+
require 'hydra_attribute/active_record/relation'
|
|
4
|
+
require 'hydra_attribute/active_record/scoping'
|
|
5
|
+
require 'hydra_attribute/active_record/mass_assignment_security'
|
|
6
|
+
|
|
1
7
|
module HydraAttribute
|
|
2
8
|
module ActiveRecord
|
|
3
|
-
|
|
4
|
-
unless base.ancestors.include?(::ActiveRecord::Base)
|
|
5
|
-
raise %(Cannot include HydraAttribute::ActiveRecord module because "#{base}" is not inherited from ActiveRecord::Base)
|
|
6
|
-
end
|
|
9
|
+
extend ActiveSupport::Concern
|
|
7
10
|
|
|
8
|
-
|
|
9
|
-
|
|
11
|
+
included do
|
|
12
|
+
unless ancestors.include?(::ActiveRecord::Base)
|
|
13
|
+
raise %(Cannot include HydraAttribute::ActiveRecord module because "#{self}" is not inherited from ActiveRecord::Base)
|
|
10
14
|
end
|
|
11
15
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
Builder.build(base)
|
|
16
|
+
unless base_class.equal?(self)
|
|
17
|
+
raise %(HydraAttribute::ActiveRecord module should be included to the base class "#{base_class}" instead of "#{self}")
|
|
18
|
+
end
|
|
16
19
|
end
|
|
17
20
|
|
|
21
|
+
include ::HydraAttribute::HydraEntity
|
|
22
|
+
include ::HydraAttribute::ActiveRecord::Scoping
|
|
23
|
+
include ::HydraAttribute::ActiveRecord::AttributeMethods
|
|
24
|
+
include ::HydraAttribute::ActiveRecord::MassAssignmentSecurity
|
|
25
|
+
|
|
18
26
|
module ClassMethods
|
|
19
|
-
def
|
|
20
|
-
if
|
|
21
|
-
|
|
27
|
+
def inspect
|
|
28
|
+
if hydra_attributes.any?
|
|
29
|
+
inspection = hydra_attributes.map do |hydra_attribute|
|
|
30
|
+
"#{hydra_attribute.name}: #{hydra_attribute.backend_type}"
|
|
31
|
+
end
|
|
32
|
+
super.sub(/\)$/, ", #{inspection.join(', ')})")
|
|
22
33
|
else
|
|
23
34
|
super
|
|
24
35
|
end
|
|
25
36
|
end
|
|
26
37
|
end
|
|
27
38
|
|
|
39
|
+
def inspect
|
|
40
|
+
if hydra_attributes.any?
|
|
41
|
+
inspection = hydra_attributes.keys.map do |name|
|
|
42
|
+
"#{name}: #{attribute_for_inspect(name)}"
|
|
43
|
+
end
|
|
44
|
+
super.sub(/>$/, ", #{inspection.join(', ')}>")
|
|
45
|
+
else
|
|
46
|
+
super
|
|
47
|
+
end
|
|
48
|
+
end
|
|
28
49
|
end
|
|
29
50
|
end
|
|
@@ -6,7 +6,6 @@ module HydraAttribute
|
|
|
6
6
|
def initialize(relation, records = [])
|
|
7
7
|
@relation = relation
|
|
8
8
|
@records = records
|
|
9
|
-
prepared_records # lock attributes
|
|
10
9
|
end
|
|
11
10
|
|
|
12
11
|
def self.run(relation, records)
|
|
@@ -16,41 +15,69 @@ module HydraAttribute
|
|
|
16
15
|
def run
|
|
17
16
|
return if records.blank?
|
|
18
17
|
|
|
19
|
-
prepared_records.keys.each_slice(in_clause_length ||
|
|
20
|
-
|
|
21
|
-
next if hydra_attribute_ids.blank?
|
|
18
|
+
prepared_records.keys.each_slice(in_clause_length || records.length) do |entity_ids|
|
|
19
|
+
grouped_hydra_attribute_ids.each do |backend_type, hydra_attribute_ids|
|
|
20
|
+
next if hydra_attribute_ids.blank? # entity doesn't have any hydra attributes for the current backend type
|
|
22
21
|
|
|
22
|
+
# set values from database
|
|
23
|
+
database_entity_and_hydra_attribute_ids = {}
|
|
23
24
|
hydra_attribute_ids.each_slice(in_clause_length || hydra_attribute_ids.length) do |attribute_ids|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
::ActiveRecord::Base.connection.select_all("SELECT id, entity_id, hydra_attribute_id, value FROM hydra_#{backend_type}_#{klass.table_name} WHERE entity_id IN (#{entity_ids.join(', ')}) AND hydra_attribute_id IN (#{attribute_ids.join(', ')})").each do |attributes|
|
|
26
|
+
# PostgreSQL driver doesn't convert values, it returns them as strings
|
|
27
|
+
id = attributes['id'].to_i
|
|
28
|
+
entity_id = attributes['entity_id'].to_i
|
|
29
|
+
hydra_attribute_id = attributes['hydra_attribute_id'].to_i
|
|
30
|
+
|
|
31
|
+
assign_hydra_value_options(id: id, entity_id: entity_id, hydra_attribute_id: hydra_attribute_id, value: attributes['value'])
|
|
32
|
+
(database_entity_and_hydra_attribute_ids[entity_id] ||= []) << hydra_attribute_id
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# set nil if attribute's value is not saved into the database
|
|
37
|
+
# these values are not persisted
|
|
38
|
+
entity_ids.each do |entity_id|
|
|
39
|
+
missing_hydra_attribute_ids = hydra_attribute_ids - Array(database_entity_and_hydra_attribute_ids[entity_id])
|
|
40
|
+
missing_hydra_attribute_ids.each do |missing_hydra_attribute_id|
|
|
41
|
+
assign_hydra_value_options(entity_id: entity_id, hydra_attribute_id: missing_hydra_attribute_id, value: nil)
|
|
27
42
|
end
|
|
28
43
|
end
|
|
29
44
|
end
|
|
30
45
|
end
|
|
31
46
|
end
|
|
32
47
|
|
|
48
|
+
def assign_hydra_value_options(options = {})
|
|
49
|
+
entity = prepared_records[options[:entity_id]]
|
|
50
|
+
assoc = entity.hydra_attribute_association
|
|
51
|
+
|
|
52
|
+
if entity.hydra_set_id
|
|
53
|
+
assoc.hydra_value_options = options.symbolize_keys if entity.hydra_set.has_hydra_attribute_id?(options[:hydra_attribute_id])
|
|
54
|
+
else
|
|
55
|
+
assoc.hydra_value_options = options.symbolize_keys
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
33
59
|
private
|
|
34
60
|
def prepared_records
|
|
35
|
-
limit = attribute_limit?
|
|
36
61
|
@prepared_records ||= records.each_with_object({}) do |record, hash|
|
|
37
|
-
|
|
38
|
-
association = record.association(association_builder.association_name(backend_type))
|
|
39
|
-
limit ? association.lock!(hydra_attribute_ids) : association.loaded!
|
|
40
|
-
end
|
|
62
|
+
record.hydra_attribute_association.lock_values
|
|
41
63
|
hash[record.id] = record
|
|
42
64
|
end
|
|
43
65
|
end
|
|
44
66
|
|
|
45
|
-
def
|
|
46
|
-
@
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
67
|
+
def grouped_hydra_attribute_ids
|
|
68
|
+
@grouped_hydra_attribute_ids ||= begin
|
|
69
|
+
hydra_attributes = ::HydraAttribute::HydraAttribute.all_by_entity_type(klass.model_name)
|
|
70
|
+
if attribute_limit?
|
|
71
|
+
map = hydra_attributes.map(&:backend_type).each_with_object({}) { |backend_type, hash| hash[backend_type] = [] }
|
|
72
|
+
relation.hydra_select_values.each_with_object(map) do |name, grouped_ids|
|
|
73
|
+
hydra_attribute = hydra_attributes.find { |attr| attr.name == name }
|
|
74
|
+
grouped_ids[hydra_attribute.backend_type] << hydra_attribute.id
|
|
75
|
+
end
|
|
76
|
+
else
|
|
77
|
+
hydra_attributes.each_with_object({}) do |hydra_attribute, hash|
|
|
78
|
+
(hash[hydra_attribute.backend_type] ||= []) << hydra_attribute.id
|
|
79
|
+
end
|
|
51
80
|
end
|
|
52
|
-
else
|
|
53
|
-
klass.hydra_attribute_ids_by_backend_type
|
|
54
81
|
end
|
|
55
82
|
end
|
|
56
83
|
|
|
@@ -58,14 +85,6 @@ module HydraAttribute
|
|
|
58
85
|
relation.select_values.any? or relation.hydra_select_values.any?
|
|
59
86
|
end
|
|
60
87
|
|
|
61
|
-
def value_class(backend_type)
|
|
62
|
-
instance_variable_get(:"@#{backend_type}_class") || instance_variable_set(:"@#{backend_type}_class", association_builder.class_name(klass, backend_type).constantize)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def association_builder
|
|
66
|
-
AssociationBuilder
|
|
67
|
-
end
|
|
68
|
-
|
|
69
88
|
def connection
|
|
70
89
|
relation.connection
|
|
71
90
|
end
|
|
@@ -3,156 +3,45 @@ module HydraAttribute
|
|
|
3
3
|
module AttributeMethods
|
|
4
4
|
extend ActiveSupport::Concern
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
included do
|
|
12
|
-
@hydra_attribute_methods_mutex = Mutex.new
|
|
6
|
+
# Returns type casted attributes
|
|
7
|
+
#
|
|
8
|
+
# @return [Hash]
|
|
9
|
+
def attributes
|
|
10
|
+
super.merge(hydra_attributes)
|
|
13
11
|
end
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def generated_hydra_attribute_methods
|
|
21
|
-
return base_class.instance_variable_get(:@generated_hydra_attribute_methods) if base_class.instance_variable_defined?(:@generated_hydra_attribute_methods)
|
|
22
|
-
|
|
23
|
-
mod = Module.new
|
|
24
|
-
base_class.send(:include, mod)
|
|
25
|
-
base_class.instance_variable_set(:@generated_hydra_attribute_methods, mod)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def define_hydra_attribute_methods
|
|
29
|
-
base_class.instance_variable_get(:@hydra_attribute_methods_mutex).synchronize do
|
|
30
|
-
return if hydra_attribute_methods_generated?
|
|
31
|
-
hydra_attributes.each { |hydra_attribute| define_hydra_attribute_method(hydra_attribute) }
|
|
32
|
-
base_class.instance_variable_set(:@hydra_attribute_methods_generated, true)
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def define_hydra_attribute_method(hydra_attribute)
|
|
37
|
-
attribute_method_matchers.each do |matcher|
|
|
38
|
-
current = matcher.method_name(hydra_attribute.name)
|
|
39
|
-
target = matcher.method_name(:value)
|
|
40
|
-
|
|
41
|
-
if current =~ NAME_COMPILABLE_REGEXP
|
|
42
|
-
defn = "def #{current}(*args)"
|
|
43
|
-
else
|
|
44
|
-
defn = "define_method(:'#{current}') do |*args|"
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
if target =~ CALL_COMPILABLE_REGEXP
|
|
48
|
-
send = "#{target}(*args)"
|
|
49
|
-
else
|
|
50
|
-
send = "send(:'#{target}', *args)"
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
generated_hydra_attribute_methods.module_eval <<-EOS, __FILE__, __LINE__ + 1
|
|
54
|
-
#{defn}
|
|
55
|
-
if hydra_set_id? and self.class.hydra_set_attribute_ids(hydra_set_id).exclude?(#{hydra_attribute.id})
|
|
56
|
-
raise MissingAttributeInHydraSetError, %(Hydra attribute "#{hydra_attribute.name}" does not exist in hydra set "\#{self.class.hydra_set(hydra_set_id).name}")
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
if value_model = hydra_value_model(#{hydra_attribute.id})
|
|
60
|
-
value_model.#{send}
|
|
61
|
-
else
|
|
62
|
-
missing_attribute('#{hydra_attribute.name}', caller)
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
EOS
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def reset_hydra_attribute_methods!
|
|
70
|
-
generated_hydra_attribute_methods.module_eval do
|
|
71
|
-
instance_methods.each { |m| undef_method(m) }
|
|
72
|
-
end
|
|
73
|
-
base_class.instance_variable_set(:@hydra_attribute_methods_generated, false)
|
|
74
|
-
|
|
75
|
-
clear_hydra_method_cache!
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def undefine_attribute_methods
|
|
79
|
-
reset_hydra_attribute_methods!
|
|
80
|
-
super
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def inspect
|
|
84
|
-
attr_list = columns.map { |c| "#{c.name}: #{c.type}" }
|
|
85
|
-
attr_list += hydra_attributes.map { |a| "#{a.name}: #{a.backend_type}" }
|
|
86
|
-
"#{name}(#{attr_list.join(', ')})"
|
|
87
|
-
end
|
|
13
|
+
# Returns attributes before type casting
|
|
14
|
+
#
|
|
15
|
+
# @return [Hash]
|
|
16
|
+
def attributes_before_type_cast
|
|
17
|
+
super.merge(hydra_attributes_before_type_cast)
|
|
88
18
|
end
|
|
89
19
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
else
|
|
99
|
-
attr_name = self.class.send(:attribute_method_matcher, name).attr_name
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
if self.class.hydra_attribute_names.include?(attr_name)
|
|
103
|
-
self.class.hydra_set_attribute_names(hydra_set_id).include?(attr_name)
|
|
20
|
+
# Read type cast attribute value by its name
|
|
21
|
+
#
|
|
22
|
+
# @param [String,Symbol] name
|
|
23
|
+
# @return [Hash]
|
|
24
|
+
def read_attribute(name)
|
|
25
|
+
name = name.to_s
|
|
26
|
+
if hydra_attributes.has_key?(name)
|
|
27
|
+
hydra_attributes[name]
|
|
104
28
|
else
|
|
105
29
|
super
|
|
106
30
|
end
|
|
107
31
|
end
|
|
108
32
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
%w(read_attribute read_attribute_before_type_cast).each do |method|
|
|
122
|
-
class_eval <<-EOS, __FILE__, __LINE__ + 1
|
|
123
|
-
def #{method}(attr_name)
|
|
124
|
-
identifier = attr_name.to_s
|
|
125
|
-
if self.class.hydra_set_attribute_names(hydra_set_id).include?(identifier)
|
|
126
|
-
if value_model = hydra_value_model(identifier)
|
|
127
|
-
value_model.#{method}('value')
|
|
128
|
-
else
|
|
129
|
-
missing_attribute(identifier, caller)
|
|
130
|
-
end
|
|
131
|
-
else
|
|
132
|
-
super
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
EOS
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
def inspect
|
|
139
|
-
attrs = hydra_value_models.map { |model| "#{model.hydra_attribute_name}: #{model.attribute_for_inspect('value')}" }
|
|
140
|
-
super.gsub(/>$/, ", #{attrs.join(', ')}>")
|
|
33
|
+
# Assigns attributes to the model
|
|
34
|
+
#
|
|
35
|
+
# @param [Hash] new_attributes
|
|
36
|
+
# @param [Hash] options
|
|
37
|
+
# @return [NilClass]
|
|
38
|
+
def assign_attributes(new_attributes, options = {})
|
|
39
|
+
if new_attributes[:hydra_set_id]
|
|
40
|
+
# set :hydra_set_id attribute as a last attribute to avoid HydraAttribute::HydraSet::MissingAttributeInHydraSetError error
|
|
41
|
+
new_attributes[:hydra_set_id] = new_attributes.delete(:hydra_set_id)
|
|
42
|
+
end
|
|
43
|
+
super
|
|
141
44
|
end
|
|
142
|
-
|
|
143
|
-
private
|
|
144
|
-
def method_missing(method, *args, &block)
|
|
145
|
-
if self.class.hydra_attribute_methods_generated?
|
|
146
|
-
super
|
|
147
|
-
else
|
|
148
|
-
self.class.define_hydra_attribute_methods
|
|
149
|
-
if respond_to_without_attributes?(method)
|
|
150
|
-
send(method, *args, &block)
|
|
151
|
-
else
|
|
152
|
-
super
|
|
153
|
-
end
|
|
154
|
-
end
|
|
155
|
-
end
|
|
156
45
|
end
|
|
157
46
|
end
|
|
158
47
|
end
|