acts_as_customized_attributes 0.0.5 → 0.0.6
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.
- checksums.yaml +8 -8
- data/README.md +10 -1
- data/app/models/acts_as_customized_attributes/data.rb +27 -1
- data/app/models/acts_as_customized_attributes/data_key.rb +26 -8
- data/lib/acts_as_customized_attributes/class_methods.rb +4 -7
- data/lib/acts_as_customized_attributes/instance_methods.rb +23 -4
- data/lib/acts_as_customized_attributes/version.rb +1 -1
- data/spec/dummy/log/test.log +5232 -0
- data/spec/models/user_spec.rb +21 -15
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
OWIxNDQ5MjA4ZjBmYzAxZDU0NDJiYTRhYzExZjMwZGE2Y2E4NDZhYg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MjM5NGRkYzIzZTBlYTUzYWU2MDljNGI0ZTAwZWE5ODAxMjM4M2Y2Zg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ODQ4MGQyNGMyMjkxYzdiOGEzNWVhYTVhYmU2MTYxNTQyM2UwZmY3ZGNiNDM0
|
10
|
+
MjRjMWVhMWI5MDllNTEwYWVhMzNkZDhkODYzNjFkODc2MGRmZGRmN2FmNzA3
|
11
|
+
MTI2NzgwYzc4NDgxOGI4ZTU3NjEzYWExN2ZmZDNiNTA3ODU0NzI=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ODM1NWFkM2FjZDY1ODUxMGZiZDhiZjYyMWExYTAzODUxYWY1ZGIyZThlZTQx
|
14
|
+
YzdhYWRmYTI4ZmVlMjE5NTFkNGQ3ZmU1ZGMxOGIzNjgxMDgyYzc2NTcxODA0
|
15
|
+
YzcwMGUxYmZmZDUzZmYzZmEwZTFlNjFiNzE0NGNhODkyYzg4Yjk=
|
data/README.md
CHANGED
@@ -33,7 +33,7 @@ class AddCustomizedAttributesForSomeModel < ActiveRecord::Migration
|
|
33
33
|
def up
|
34
34
|
SomeModel.create_customized_attributes!
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
def down
|
38
38
|
SomeModel.drop_customized_attributes!
|
39
39
|
end
|
@@ -68,6 +68,15 @@ SomeModel::DataKey.where("name LIKE '%facebook%'")
|
|
68
68
|
SomeModel::Data.where("resource_id > 5")
|
69
69
|
```
|
70
70
|
|
71
|
+
### Optimize inserts with transactions for inserts / updates.
|
72
|
+
```ruby
|
73
|
+
ActiveRecordTransactioner.new do |trans|
|
74
|
+
models.each do |model|
|
75
|
+
model.update_customized_attributes_with_args(data: {my_custom_attribute: 5}, transactioner: trans)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
```
|
79
|
+
|
71
80
|
## License
|
72
81
|
|
73
82
|
This project uses MIT-LICENSE.
|
@@ -1,3 +1,29 @@
|
|
1
1
|
class ActsAsCustomizedAttributes::Data < ActiveRecord::Base
|
2
|
-
|
2
|
+
validate :associated_resource_and_data_key
|
3
|
+
|
4
|
+
def self.key_class=(key_class)
|
5
|
+
@key_class = key_class
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.key_class
|
9
|
+
return @key_class
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def associated_resource_and_data_key
|
15
|
+
unless data_key_id?
|
16
|
+
return errors.add :data_key_id, "not valid"
|
17
|
+
end
|
18
|
+
|
19
|
+
if !resource_id? || !resource
|
20
|
+
return errors.add :resource_id, "not associated"
|
21
|
+
end
|
22
|
+
|
23
|
+
begin
|
24
|
+
self.class.key_class.name_for_id(data_key_id)
|
25
|
+
rescue KeyError
|
26
|
+
errors.add :data_key_id, "doesn't exist"
|
27
|
+
end
|
28
|
+
end
|
3
29
|
end
|
@@ -1,5 +1,11 @@
|
|
1
1
|
class ActsAsCustomizedAttributes::DataKey < ActiveRecord::Base
|
2
|
+
after_create :add_to_cache
|
3
|
+
after_update :add_to_cache
|
4
|
+
after_destroy :remove_from_cache
|
5
|
+
before_update :remove_from_cache
|
6
|
+
|
2
7
|
validates_presence_of :name
|
8
|
+
validate :validate_unique_name
|
3
9
|
|
4
10
|
def self.id_for_name(name)
|
5
11
|
cache_name_to_id.fetch(name.to_s)
|
@@ -9,26 +15,38 @@ class ActsAsCustomizedAttributes::DataKey < ActiveRecord::Base
|
|
9
15
|
cache_name_to_id.key(id) or raise KeyError, "No such ID: #{id}"
|
10
16
|
end
|
11
17
|
|
12
|
-
|
18
|
+
def self.cache_name_to_id
|
19
|
+
update_cache_name_to_id unless @cache_name_to_id
|
20
|
+
return @cache_name_to_id
|
21
|
+
end
|
13
22
|
|
14
23
|
# Initializes / reloads the cache.
|
15
24
|
def self.update_cache_name_to_id
|
16
|
-
|
25
|
+
@cache_name_to_id = {}
|
17
26
|
find_each do |data_key|
|
18
|
-
|
27
|
+
@cache_name_to_id[data_key.name] = data_key.id
|
19
28
|
end
|
20
29
|
end
|
21
30
|
|
22
|
-
|
23
|
-
update_cache_name_to_id unless @cache_name_to_id
|
24
|
-
return @@cache_name_to_id
|
25
|
-
end
|
31
|
+
private
|
26
32
|
|
27
33
|
def add_to_cache
|
28
34
|
self.class.cache_name_to_id[name.to_s] = id
|
29
35
|
end
|
30
36
|
|
31
37
|
def remove_from_cache
|
32
|
-
self.class.cache_name_to_id.delete(
|
38
|
+
self.class.cache_name_to_id.delete(name_was)
|
39
|
+
end
|
40
|
+
|
41
|
+
def validate_unique_name
|
42
|
+
begin
|
43
|
+
id_exists = self.class.id_for_name(name)
|
44
|
+
|
45
|
+
if id_exists != id
|
46
|
+
errors.add :name, :taken
|
47
|
+
end
|
48
|
+
rescue KeyError
|
49
|
+
# No problem.
|
50
|
+
end
|
33
51
|
end
|
34
52
|
end
|
@@ -2,29 +2,26 @@ module ActsAsCustomizedAttributes::ClassMethods
|
|
2
2
|
def acts_as_customized_attributes(args = {})
|
3
3
|
$aaca_class_name_key = "#{name}DataKey"
|
4
4
|
$aaca_class_name_data = "#{name}Data"
|
5
|
+
$original_class_name = name
|
5
6
|
|
6
7
|
class_data_key = Class.new(ActsAsCustomizedAttributes::DataKey) do
|
7
8
|
set_table_name $aaca_class_name_key.tableize
|
8
9
|
|
9
10
|
has_many :data, class_name: $aaca_class_name_data, foreign_key: "data_key_id", dependent: :destroy
|
10
|
-
|
11
|
-
after_create :add_to_cache
|
12
|
-
after_update :add_to_cache
|
13
|
-
after_destroy :remove_from_cache
|
14
|
-
before_update :remove_from_cache
|
15
11
|
end
|
16
12
|
|
17
13
|
class_data = Class.new(ActsAsCustomizedAttributes::Data) do
|
18
14
|
set_table_name $aaca_class_name_data.tableize
|
19
15
|
|
16
|
+
belongs_to :resource, class_name: $original_class_name
|
20
17
|
belongs_to :data_key, class_name: $aaca_class_name_key
|
21
|
-
|
22
|
-
validates_associated :data_key
|
23
18
|
end
|
24
19
|
|
25
20
|
Object.const_set($aaca_class_name_key, class_data_key)
|
26
21
|
Object.const_set($aaca_class_name_data, class_data)
|
27
22
|
|
23
|
+
class_data.key_class = Object.const_get($aaca_class_name_key)
|
24
|
+
|
28
25
|
include ActsAsCustomizedAttributes::InstanceMethods
|
29
26
|
|
30
27
|
has_many :data, class_name: "#{name}Data", foreign_key: "resource_id", dependent: :destroy
|
@@ -1,6 +1,13 @@
|
|
1
1
|
module ActsAsCustomizedAttributes::InstanceMethods
|
2
2
|
def update_customized_attributes(data)
|
3
|
-
data
|
3
|
+
update_customized_attributes_with_args(data: data)
|
4
|
+
end
|
5
|
+
|
6
|
+
UPDATE_CUSTOMIZED_ATTRIBUTES_VALID_ARGS = [:data, :transactioner]
|
7
|
+
def update_customized_attributes_with_args(args)
|
8
|
+
args.each { |key, value| raise "Invalid argument: '#{key}'." unless UPDATE_CUSTOMIZED_ATTRIBUTES_VALID_ARGS.include?(key) }
|
9
|
+
|
10
|
+
args[:data].each do |key, value|
|
4
11
|
begin
|
5
12
|
key_id = self.class.aaca_key_class.id_for_name(key)
|
6
13
|
rescue KeyError
|
@@ -8,9 +15,21 @@ module ActsAsCustomizedAttributes::InstanceMethods
|
|
8
15
|
key_id = key_model.id
|
9
16
|
end
|
10
17
|
|
11
|
-
|
12
|
-
|
13
|
-
|
18
|
+
data_model = self.data.where(data_key_id: key_id).first
|
19
|
+
if data_model
|
20
|
+
data_model.resource = self # Saves query when validating.
|
21
|
+
else
|
22
|
+
# Set resource in order to skip query when validating.
|
23
|
+
data_model = self.data.new(data_key_id: key_id, resource: self)
|
24
|
+
end
|
25
|
+
|
26
|
+
data_model.value = value
|
27
|
+
|
28
|
+
if args[:transactioner]
|
29
|
+
args[:transactioner].save!(data_model)
|
30
|
+
else
|
31
|
+
data_model.save!
|
32
|
+
end
|
14
33
|
end
|
15
34
|
end
|
16
35
|
|