activerecord-redundancy 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ea48053646bbb9a46bac56dbdfbb38421deba343
4
- data.tar.gz: d773a73fa5b34e872888e085d82b4f623de8b53e
3
+ metadata.gz: faa2836ac314098d90878058bf77c1260a99decc
4
+ data.tar.gz: b6494ce4bbfdaf61a9eb799ad9daf418eeb76483
5
5
  SHA512:
6
- metadata.gz: d23cb5550eff70b10fad7f3f57b6a97ca5e9e494d6b3695d40a1459696bce13d9223c19da9bdaa84aac380297fa25ba66530f70c9de346f232bf055210da997f
7
- data.tar.gz: 39d26a0d4e8a438ed0aecb02af153188a1762719c5d6fbd76a6a078281705d5409ae3fbf229a3db7fcaae0be0fe40247476a00910462ba89a6f7f5e231a66d64
6
+ metadata.gz: 078c06ecc0f44628b258e97c6ca3290f0ce209ad450e5f84eb2f419e62c8c387e93fb236727e77179e35880c34b9499733e5de3e4a1ece02b954e98a37df0d02
7
+ data.tar.gz: 2f0cb3ee7453469962e52b95104450a40cae0308616447f775237dea18bf875d6a51cb923a25982d0e9a16e31c608c3af5283d62d110309f25cab0367028c4db
data/lib/redundancy.rb CHANGED
@@ -1,73 +1,47 @@
1
- require 'redundancy/cache_column'
1
+ require 'redundancy/utils'
2
2
 
3
3
  module Redundancy
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  included do
7
- before_save :redundancy_update_cache_column_after_save
7
+ before_save :update_redundacies_before_save
8
+ after_save :update_redundacies_after_save
8
9
  end
9
10
 
10
11
  private
11
12
 
12
- def redundancy_update_cache_column_after_save
13
- self.class.cache_columns.each do |cache_column|
14
- cache_column.update_record(self)
13
+ def update_redundacies_before_save
14
+ self.class.redundacies.each do |redundancy|
15
+ redundancy.before_save(self)
15
16
  end
16
17
  end
17
18
 
18
- module ClassMethods
19
- def redundancy association, attribute, options = {}
20
- options.assert_valid_keys(:cache_column, :inverse_of)
21
-
22
- reflection = self.reflect_on_association(association)
23
- raise ArgumentError, "Unknown association :#{association}" unless reflection
24
- raise ArgumentError, "BelongsTo or HasOne reflection needed" unless
25
- [:has_one, :belongs_to].include? reflection.macro
26
-
27
- inverse_associations = options[:inverse_of]
28
- inverse_associations ||= [model_name.plural, model_name.singular].map(&:to_sym)
29
-
30
- inverse_association = Array.wrap(inverse_associations).find do |inverse_association|
31
- reflection.klass.reflect_on_association(inverse_association)
32
- end
33
-
34
- raise ArgumentError, "Could not find the inverse association for #{association} (#{inverse_associations.inspect} in #{reflection.klass})" unless inverse_association
35
-
36
- foreign_key = reflection.foreign_key
37
- cache_column = options[:cache_column] || :"#{association}_#{attribute}"
38
-
39
- local_klass = self
40
- remote_klass = reflection.klass
41
-
42
- case reflection.macro
43
- when :belongs_to
44
- local_klass.cache_columns << CacheColumn.new({
45
- source: { association: association, attribute: attribute },
46
- dist: { association: nil, attribute: cache_column },
47
- change_if: foreign_key, klass: local_klass
48
- })
49
-
50
- when :has_one
51
- remote_klass.cache_columns << CacheColumn.new({
52
- source: { association: nil, attribute: attribute },
53
- dist: { association: inverse_association, attribute: cache_column },
54
- change_if: foreign_key, nil_unless: foreign_key, klass: remote_klass,
55
- set_prev_nil: { klass: local_klass, attribute: foreign_key }
56
- })
57
-
58
- end
19
+ def update_redundacies_after_save
20
+ self.class.redundacies.each do |redundancy|
21
+ redundancy.after_save(self)
22
+ end
23
+ end
59
24
 
60
- remote_klass.cache_columns << CacheColumn.new({
61
- source: { association: nil, attribute: attribute },
62
- dist: { association: inverse_association, attribute: cache_column },
63
- change_if: attribute, klass: remote_klass, update: true
64
- })
25
+ def update_redundacies
26
+ self.class.redundacies.each do |redundancy|
27
+ redundancy.before_save(self)
28
+ redundancy.after_save(self)
29
+ end
30
+ end
65
31
 
32
+ module ClassMethods
33
+ def cache_column association, attribute, options = {}
34
+ options.assert_valid_keys(:cache_column, :inverse_of)
35
+ Utils.cache_column self, association, attribute, options
36
+ end
66
37
 
38
+ def cache_method association, attribute, options = {}
39
+ options.assert_valid_keys(:cache_column, :inverse_of)
40
+ Utils.cache_method self, association, attribute, options
67
41
  end
68
42
 
69
- def cache_columns
70
- @cache_columns ||= []
43
+ def redundacies
44
+ @redundacies ||= []
71
45
  end
72
46
 
73
47
  end
@@ -77,4 +51,4 @@ end
77
51
  # include in AR
78
52
  ActiveSupport.on_load(:active_record) do
79
53
  ActiveRecord::Base.send(:include, Redundancy)
80
- end
54
+ end
@@ -0,0 +1,88 @@
1
+ module Redundancy
2
+
3
+ class UpdateBase
4
+ attr_reader :options
5
+ attr_reader :source, :dest, :klass
6
+ attr_reader :change_if, :update, :target, :value
7
+
8
+ def initialize options
9
+ @options = options
10
+ @source, @dest = options[:source], options[:dest]
11
+ @klass = options[:klass]
12
+
13
+ @change_if = options[:change_if]
14
+ @update = options[:update] || false
15
+ end
16
+
17
+ def before_save record
18
+ end
19
+
20
+ def after_save record
21
+ end
22
+
23
+ def get_target_from_association record
24
+ @target = dest[:association] ? record.send(dest[:association]) : record
25
+ end
26
+
27
+ def get_target_from_prev_id record
28
+ prev_id = record.send(:attribute_was, dest[:prev_id])
29
+ return unless prev_id
30
+ @target = dest[:klass].where(id: prev_id)
31
+ end
32
+
33
+ def get_target_from_relation_first_record
34
+ @target = @target.first if @target.kind_of? ActiveRecord::Relation
35
+ end
36
+
37
+ def get_value_from_association record
38
+ @value = source[:association] ? record.send(source[:association]) : record
39
+ @value = value && source[:attribute] && value.send(source[:attribute])
40
+ @value = nil if source[:nil_unless] && !record.send(source[:nil_unless])
41
+ @value
42
+ end
43
+
44
+ def get_value_from_source record
45
+ @value = source
46
+ end
47
+
48
+ def get_value_from_target record
49
+ @value = target && source[:attribute] && target.send(source[:attribute])
50
+ end
51
+
52
+ def raise_if_class_mismatch record
53
+ raise ArgumentError, "record class mismatch, expected #{klass}, got #{record.class}" unless record.kind_of? klass
54
+ end
55
+
56
+ def update_target record
57
+ case target
58
+ when ActiveRecord::Base
59
+ return if target.send(:read_attribute, dest[:attribute]) == value
60
+ log "#{ update ? "update" : "write" } #{target.class}(#{target.id})##{dest[:attribute]} with #{value.inspect}"
61
+ log "#{change_if}: #{record.send(change_if).inspect}, #{dest[:association]||"self"}.id: #{target.id}" if change_if
62
+ if update
63
+ target.send(:update_attribute, dest[:attribute], value)
64
+ else
65
+ target.send(:write_attribute, dest[:attribute], value)
66
+ end
67
+ when ActiveRecord::Relation
68
+ log "update #{target.class}##{dest[:attribute]} with #{value.inspect}"
69
+ target.send(:update_all, dest[:attribute] => value)
70
+ end
71
+ end
72
+
73
+ def force_update_target record
74
+ @update = true
75
+ update_target record
76
+ end
77
+
78
+ def need_update? record
79
+ !change_if || record.send(:attribute_changed?, change_if)
80
+ end
81
+
82
+ def log *message
83
+ # puts *message
84
+ end
85
+
86
+ end
87
+
88
+ end
@@ -0,0 +1,19 @@
1
+ require 'redundancy/update_base'
2
+
3
+ module Redundancy
4
+
5
+ class UpdateColumn < UpdateBase
6
+
7
+ def before_save record
8
+ raise_if_class_mismatch record
9
+ return unless need_update? record
10
+
11
+ get_target_from_association record
12
+ get_value_from_association record
13
+
14
+ update_target record
15
+ end
16
+
17
+ end
18
+
19
+ end
@@ -0,0 +1,19 @@
1
+ require 'redundancy/update_base'
2
+
3
+ module Redundancy
4
+
5
+ class UpdateMethod < UpdateBase
6
+
7
+ def after_save record
8
+ raise_if_class_mismatch record
9
+ return unless need_update? record
10
+
11
+ get_target_from_association record
12
+ get_value_from_target record
13
+
14
+ force_update_target record
15
+ end
16
+
17
+ end
18
+
19
+ end
@@ -0,0 +1,19 @@
1
+ require 'redundancy/update_base'
2
+
3
+ module Redundancy
4
+
5
+ class UpdatePrevColumn < UpdateBase
6
+
7
+ def before_save record
8
+ raise_if_class_mismatch record
9
+ return unless need_update? record
10
+
11
+ get_target_from_prev_id record
12
+ get_value_from_source record
13
+
14
+ update_target record
15
+ end
16
+
17
+ end
18
+
19
+ end
@@ -0,0 +1,25 @@
1
+ require 'redundancy/update_base'
2
+
3
+ module Redundancy
4
+
5
+ class UpdatePrevMethod < UpdateBase
6
+
7
+ def before_save record
8
+ raise_if_class_mismatch record
9
+ return unless need_update? record
10
+
11
+ get_target_from_prev_id record
12
+ end
13
+
14
+ def after_save record
15
+ return unless need_update? record
16
+ return unless target
17
+
18
+ get_target_from_relation_first_record
19
+ get_value_from_target record
20
+ force_update_target record
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,102 @@
1
+ require 'redundancy/update_column'
2
+ require 'redundancy/update_prev_column'
3
+ require 'redundancy/update_method'
4
+ require 'redundancy/update_prev_method'
5
+
6
+ module Redundancy
7
+
8
+ module Utils
9
+
10
+ def self.cache_column klass, association, attribute, options
11
+ local_klass = klass
12
+
13
+ reflection = get_reflection local_klass, association
14
+ raise ArgumentError, "BelongsTo or HasOne reflection required" unless
15
+ [:has_one, :belongs_to].include? reflection.macro
16
+
17
+ foreign_key = reflection.foreign_key
18
+ remote_klass = reflection.klass
19
+
20
+ inverse_association = get_inverse_association local_klass, remote_klass, options
21
+
22
+ cache_column = options[:cache_column] || :"#{association}_#{attribute}"
23
+
24
+ case reflection.macro
25
+ when :belongs_to
26
+ local_klass.redundacies << UpdateColumn.new(
27
+ source: { association: association, attribute: attribute },
28
+ dest: { association: nil, attribute: cache_column },
29
+ change_if: foreign_key, klass: local_klass
30
+ )
31
+
32
+ when :has_one
33
+ remote_klass.redundacies << UpdateColumn.new(
34
+ source: { association: nil, attribute: attribute, nil_unless: foreign_key },
35
+ dest: { association: inverse_association, attribute: cache_column },
36
+ change_if: foreign_key, klass: remote_klass
37
+ )
38
+
39
+ remote_klass.redundacies << UpdatePrevColumn.new(
40
+ source: options[:default],
41
+ dest: { klass: local_klass, prev_id: foreign_key, attribute: cache_column },
42
+ change_if: foreign_key, klass: remote_klass
43
+ )
44
+
45
+ end
46
+
47
+ remote_klass.redundacies << UpdateColumn.new(
48
+ source: { association: nil, attribute: attribute },
49
+ dest: { association: inverse_association, attribute: cache_column },
50
+ change_if: attribute, klass: remote_klass, update: true
51
+ )
52
+ end
53
+
54
+ def self.cache_method klass, association, attribute, options
55
+ local_klass = klass
56
+
57
+ reflection = get_reflection local_klass, association
58
+ raise ArgumentError, "BelongsTo reflection required" unless
59
+ [:belongs_to].include? reflection.macro
60
+
61
+ foreign_key = reflection.foreign_key
62
+ remote_klass = reflection.klass
63
+
64
+ cache_method = options[:cache_method] || :"raw_#{attribute}"
65
+
66
+ local_klass.redundacies << UpdateMethod.new(
67
+ source: { attribute: cache_method },
68
+ dest: { association: association, attribute: attribute },
69
+ change_if: options[:change_if], klass: local_klass
70
+ )
71
+
72
+ local_klass.redundacies << UpdatePrevMethod.new(
73
+ source: { attribute: cache_method },
74
+ dest: { klass: remote_klass, prev_id: foreign_key, attribute: attribute },
75
+ change_if: foreign_key, klass: local_klass
76
+ )
77
+
78
+ end
79
+
80
+ def self.get_reflection klass, association
81
+ reflection = klass.reflect_on_association(association)
82
+ raise ArgumentError, "Unknown association :#{association}" unless reflection
83
+ reflection
84
+ end
85
+
86
+ def self.get_inverse_association klass, reflection_klass, options
87
+ model_name = klass.model_name
88
+ inverse_associations = options[:inverse_of]
89
+ inverse_associations ||= [model_name.plural, model_name.singular].map(&:to_sym)
90
+
91
+ inverse_association = Array.wrap(inverse_associations).find do |inverse_association|
92
+ reflection_klass.reflect_on_association(inverse_association)
93
+ end
94
+
95
+ raise ArgumentError, "Could not find the inverse association for #{association} (#{inverse_associations.inspect} in #{reflection_klass})" unless inverse_association
96
+ inverse_association
97
+ end
98
+
99
+
100
+ end
101
+
102
+ end
@@ -1,3 +1,3 @@
1
1
  module Redundancy
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -21,6 +21,7 @@ class BelongsToHasOneAssociationTest < ActiveSupport::TestCase
21
21
 
22
22
  account.update_attribute(:user, user)
23
23
  assert_equal user.name, account.user_name
24
+ assert_equal user.name, account.reload.user_name
24
25
  end
25
26
 
26
27
  test "should update account.user_name when update account.user with nil" do
@@ -30,6 +31,7 @@ class BelongsToHasOneAssociationTest < ActiveSupport::TestCase
30
31
 
31
32
  account.update_attribute(:user, nil)
32
33
  assert_equal nil, account.user_name
34
+ assert_equal nil, account.reload.user_name
33
35
  end
34
36
 
35
37
  test "should update account.user_name when update account.user with other user" do
@@ -42,7 +44,8 @@ class BelongsToHasOneAssociationTest < ActiveSupport::TestCase
42
44
 
43
45
  account.update_attribute(:user, other_user)
44
46
  assert_equal other_user.name, account.user_name
45
- assert_equal nil, other_account.reload.user
47
+ assert_equal other_user.name, account.reload.user_name
48
+ assert_equal nil, other_account.user
46
49
  assert_equal nil, other_account.reload.user_name
47
50
  end
48
51
 
@@ -53,8 +56,7 @@ class BelongsToHasOneAssociationTest < ActiveSupport::TestCase
53
56
 
54
57
  user.update_attribute(:name, "Other Name")
55
58
  assert_equal user.name, user.account.user_name
56
-
57
59
  assert_equal user.name, account.reload.user_name
58
60
  end
59
61
 
60
- end
62
+ end
@@ -3,6 +3,7 @@ require 'test_helper'
3
3
  class HasManyBelongsToAssociationTest < ActiveSupport::TestCase
4
4
 
5
5
  # has_many:belongs_to association
6
+ # cache_column
6
7
  test "should update post.user_name when create post" do
7
8
  user = users(:one)
8
9
  post = Post.create(title: 'title', content: 'content', user: user)
@@ -21,6 +22,7 @@ class HasManyBelongsToAssociationTest < ActiveSupport::TestCase
21
22
 
22
23
  post.update_attribute(:user, user)
23
24
  assert_equal user.name, post.user_name
25
+ assert_equal user.name, post.reload.user_name
24
26
  end
25
27
 
26
28
  test "should update post.user_name when update post.user with nil" do
@@ -30,6 +32,7 @@ class HasManyBelongsToAssociationTest < ActiveSupport::TestCase
30
32
 
31
33
  post.update_attribute(:user, nil)
32
34
  assert_equal nil, post.user_name
35
+ assert_equal nil, post.reload.user_name
33
36
  end
34
37
 
35
38
  test "should update post.user_name when update post.user with other user" do
@@ -42,6 +45,7 @@ class HasManyBelongsToAssociationTest < ActiveSupport::TestCase
42
45
 
43
46
  post.update_attribute(:user, other_user)
44
47
  assert_equal other_user.name, post.user_name
48
+ assert_equal other_user.name, post.reload.user_name
45
49
  end
46
50
 
47
51
  test "should update post.user_name when update user.name" do
@@ -53,8 +57,6 @@ class HasManyBelongsToAssociationTest < ActiveSupport::TestCase
53
57
  user.posts.each do |post|
54
58
  assert_equal user.name, post.user_name
55
59
  end
56
-
57
60
  assert_equal user.name, post.reload.user_name
58
61
  end
59
-
60
62
  end
@@ -21,6 +21,7 @@ class HasOneBelongsToAssociationTest < ActiveSupport::TestCase
21
21
 
22
22
  user.update_attribute(:account, account)
23
23
  assert_equal account.email, user.account_email
24
+ assert_equal account.email, user.reload.account_email
24
25
  end
25
26
 
26
27
  test "should update user.account_email when update user.account with nil" do
@@ -30,6 +31,7 @@ class HasOneBelongsToAssociationTest < ActiveSupport::TestCase
30
31
 
31
32
  user.update_attribute(:account, nil)
32
33
  assert_equal nil, user.account_email
34
+ assert_equal nil, user.reload.account_email
33
35
  end
34
36
 
35
37
  test "should update user.account_email when update user.account with other account" do
@@ -42,8 +44,10 @@ class HasOneBelongsToAssociationTest < ActiveSupport::TestCase
42
44
 
43
45
  user.update_attribute(:account, other_account)
44
46
  assert_equal other_account.email, user.account_email
47
+ assert_equal other_account.email, user.reload.account_email
45
48
  assert_equal other_account, other_user.account
46
49
  assert_equal other_account.email, other_user.account_email
50
+ assert_equal other_account.email, other_user.reload.account_email
47
51
  end
48
52
 
49
53
  test "should update user.account_email when update account.email" do
@@ -57,4 +61,4 @@ class HasOneBelongsToAssociationTest < ActiveSupport::TestCase
57
61
  assert_equal account.email, user.reload.account_email
58
62
  end
59
63
 
60
- end
64
+ end
@@ -0,0 +1,70 @@
1
+ require 'test_helper'
2
+
3
+ class HasManyBelongsToAssociationTest < ActiveSupport::TestCase
4
+
5
+ # has_many:belongs_to association
6
+ # cache_method
7
+ test "should update user.posts_count when create post" do
8
+ user = users(:one)
9
+ post = Post.create(title: 'title', content: 'content', user: user)
10
+ assert_equal user.raw_posts_count, user.posts_count
11
+ end
12
+
13
+ test "should update user.posts_star when create post" do
14
+ user = users(:one)
15
+ post = Post.create(title: 'title', content: 'content', user: user, star: 5)
16
+ assert_equal user.raw_posts_star, user.posts_star
17
+ end
18
+
19
+ test "should update user.posts_star when create post without star" do
20
+ user = users(:one)
21
+ post = Post.create(title: 'title', content: 'content', user: user)
22
+ assert_equal user.raw_posts_star, user.posts_star
23
+ end
24
+
25
+ test "should update nothing when create post without user" do
26
+ post = Post.create(title: 'title', content: 'content')
27
+ end
28
+
29
+ test "should update user.posts_star when update post.user" do
30
+ user = users(:one)
31
+ post = posts(:two)
32
+ assert_equal user.raw_posts_star, user.posts_star
33
+
34
+ post.update_attribute(:user, user)
35
+ assert_equal user.raw_posts_star, user.reload.posts_star
36
+ end
37
+
38
+ test "should update user.posts_star when update post.user with nil" do
39
+ user = users(:one)
40
+ post = posts(:one)
41
+ assert_equal user.raw_posts_star, user.posts_star
42
+
43
+ post.update_attribute(:user, nil)
44
+ assert_equal user.raw_posts_star, user.reload.posts_star
45
+ end
46
+
47
+ test "should update user.posts_star when update post.user with other user" do
48
+ user = users(:one)
49
+ other_user = users(:two)
50
+ post = posts(:one)
51
+ other_post = posts(:two)
52
+ assert_equal user.raw_posts_star, user.posts_star
53
+ assert_equal other_user.raw_posts_star, other_user.posts_star
54
+
55
+ post.update_attribute(:user, other_user)
56
+ assert_equal user.raw_posts_star, user.reload.posts_star
57
+ assert_equal other_user.raw_posts_star, other_user.reload.posts_star
58
+ end
59
+
60
+ test "should update user.posts_star when update post.star" do
61
+ user = users(:one)
62
+ post = posts(:one)
63
+ assert_equal user.raw_posts_star, user.posts_star
64
+
65
+ post.update_attribute(:star, 5)
66
+ assert_equal user.raw_posts_star, post.user.posts_star
67
+ assert_equal user.raw_posts_star, user.reload.posts_star
68
+ end
69
+
70
+ end
@@ -7,6 +7,7 @@ one:
7
7
  user_id: 1
8
8
  user_name: Name 1
9
9
  username: Name 1
10
+ star: 3
10
11
 
11
12
  two:
12
13
  id: 2
@@ -15,3 +16,4 @@ two:
15
16
  user_id: 2
16
17
  user_name: Name 2
17
18
  username: Name 2
19
+ star: 5
@@ -5,9 +5,11 @@ one:
5
5
  name: Name 1
6
6
  account_id: 1
7
7
  account_email: one@one.com
8
+ posts_star: 3
8
9
 
9
10
  two:
10
11
  id: 2
11
12
  name: Name 2
12
13
  account_id: 2
13
14
  account_email: two@two.com
15
+ posts_star: 5
@@ -22,6 +22,7 @@ ActiveRecord::Schema.define do
22
22
  t.integer "user_id"
23
23
  t.string "user_name"
24
24
  t.string "username"
25
+ t.integer "star"
25
26
  t.string "title"
26
27
  t.text "content"
27
28
  t.datetime "created_at"
@@ -33,6 +34,8 @@ ActiveRecord::Schema.define do
33
34
  create_table "users", force: true do |t|
34
35
  t.integer "account_id"
35
36
  t.string "account_email"
37
+ t.integer "posts_count"
38
+ t.integer "posts_star"
36
39
  t.string "name"
37
40
  t.datetime "created_at"
38
41
  t.datetime "updated_at"
@@ -1,5 +1,5 @@
1
1
  class Account < ActiveRecord::Base
2
2
  has_one :user
3
-
4
- redundancy :user, :name
3
+
4
+ cache_column :user, :name
5
5
  end
@@ -1,6 +1,9 @@
1
1
  class Post < ActiveRecord::Base
2
2
  belongs_to :user
3
3
 
4
- redundancy :user, :name
5
- redundancy :user, :name, cache_column: :username
4
+ cache_column :user, :name
5
+ cache_column :user, :name, cache_column: :username
6
+
7
+ cache_method :user, :posts_count
8
+ cache_method :user, :posts_star
6
9
  end
@@ -2,5 +2,13 @@ class User < ActiveRecord::Base
2
2
  has_many :posts
3
3
  belongs_to :account
4
4
 
5
- redundancy :account, :email
5
+ cache_column :account, :email
6
+
7
+ def raw_posts_count
8
+ posts.count
9
+ end
10
+
11
+ def raw_posts_star
12
+ posts.average(:star)
13
+ end
6
14
  end
data/test/test_helper.rb CHANGED
@@ -20,3 +20,5 @@ ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__)
20
20
  class ActiveSupport::TestCase
21
21
  fixtures :all
22
22
  end
23
+
24
+ ActiveSupport.test_order = :sorted
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-redundancy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Theo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-18 00:00:00.000000000 Z
11
+ date: 2015-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -58,6 +58,20 @@ dependencies:
58
58
  - - ">="
59
59
  - !ruby/object:Gem::Version
60
60
  version: '0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: pry-stack_explorer
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
61
75
  - !ruby/object:Gem::Dependency
62
76
  name: rails
63
77
  requirement: !ruby/object:Gem::Requirement
@@ -83,15 +97,21 @@ files:
83
97
  - Rakefile
84
98
  - lib/activerecord-redundancy.rb
85
99
  - lib/redundancy.rb
86
- - lib/redundancy/cache_column.rb
100
+ - lib/redundancy/update_base.rb
101
+ - lib/redundancy/update_column.rb
102
+ - lib/redundancy/update_method.rb
103
+ - lib/redundancy/update_prev_column.rb
104
+ - lib/redundancy/update_prev_method.rb
105
+ - lib/redundancy/utils.rb
87
106
  - lib/redundancy/version.rb
88
- - test/belongs_to_has_one_association_test.rb
107
+ - test/cache_column/belongs_to_has_one_association_test.rb
108
+ - test/cache_column/has_many_belongs_to_association_test.rb
109
+ - test/cache_column/has_one_belongs_to_association_test.rb
110
+ - test/cache_column/options_test.rb
111
+ - test/cache_method/has_many_belongs_to_association_test.rb
89
112
  - test/fixtures/accounts.yml
90
113
  - test/fixtures/posts.yml
91
114
  - test/fixtures/users.yml
92
- - test/has_many_belongs_to_association_test.rb
93
- - test/has_one_belongs_to_association_test.rb
94
- - test/options_test.rb
95
115
  - test/support/environment.rb
96
116
  - test/support/models/account.rb
97
117
  - test/support/models/post.rb
@@ -117,18 +137,19 @@ required_rubygems_version: !ruby/object:Gem::Requirement
117
137
  version: '0'
118
138
  requirements: []
119
139
  rubyforge_project:
120
- rubygems_version: 2.2.2
140
+ rubygems_version: 2.4.6
121
141
  signing_key:
122
142
  specification_version: 4
123
143
  summary: Redundancy for better performance, non painful
124
144
  test_files:
125
- - test/belongs_to_has_one_association_test.rb
145
+ - test/cache_column/belongs_to_has_one_association_test.rb
146
+ - test/cache_column/has_many_belongs_to_association_test.rb
147
+ - test/cache_column/has_one_belongs_to_association_test.rb
148
+ - test/cache_column/options_test.rb
149
+ - test/cache_method/has_many_belongs_to_association_test.rb
126
150
  - test/fixtures/accounts.yml
127
151
  - test/fixtures/posts.yml
128
152
  - test/fixtures/users.yml
129
- - test/has_many_belongs_to_association_test.rb
130
- - test/has_one_belongs_to_association_test.rb
131
- - test/options_test.rb
132
153
  - test/support/environment.rb
133
154
  - test/support/models/account.rb
134
155
  - test/support/models/post.rb
@@ -1,59 +0,0 @@
1
- module Redundancy
2
-
3
- class CacheColumn
4
- attr_reader :options
5
- attr_reader :source, :dist, :klass
6
- attr_reader :change_if, :nil_unless, :update, :set_prev_nil
7
-
8
- def initialize options
9
- @options = options
10
- @source, @dist = options[:source], options[:dist]
11
- @klass = options[:klass]
12
-
13
- @change_if = options[:change_if]
14
- @nil_unless = options[:nil_unless]
15
- @update = options[:update] || false
16
- @set_prev_nil = options[:set_prev_nil]
17
- end
18
-
19
- def update_record record
20
- raise ArgumentError, "record class mismatch, expected #{klass}, got #{record.class}" unless record.kind_of? klass
21
- return unless need_update?(record)
22
-
23
- src = source[:association] ? record.send(source[:association]) : record
24
- src = src && source[:attribute] && src.send(source[:attribute])
25
- src = nil if nil_unless && !record.send(nil_unless)
26
-
27
- dst = dist[:association] ? record.send(dist[:association]) : record
28
-
29
- set_prev_nil[:klass].where(id: record.send(:attribute_was, set_prev_nil[:attribute]))
30
- .update_all(dist[:attribute] => nil) if set_prev_nil
31
-
32
- case dst
33
- when ActiveRecord::Base
34
- return if dst.send(:read_attribute, dist[:attribute]) == src
35
- log "#{ update ? "update" : "write" } #{dst.class}(#{dst.id})##{dist[:attribute]} with #{src.inspect}"
36
- log "#{change_if}: #{record.send(change_if).inspect}, #{dist[:association]||"self"}.id: #{dst.id}"
37
- if update
38
- dst.send(:update_attribute, dist[:attribute], src)
39
- else
40
- dst.send(:write_attribute, dist[:attribute], src)
41
- end
42
- when ActiveRecord::Relation
43
- log "update #{dst.class}##{dist[:attribute]} with #{src.inspect}"
44
- dst.send(:update_all, dist[:attribute] => src)
45
- end
46
-
47
- end
48
-
49
- def need_update? record
50
- record.send(:attribute_changed?, change_if)
51
- end
52
-
53
- def log *message
54
- # puts *message
55
- end
56
-
57
- end
58
-
59
- end