redundant_column 0.0.1 → 0.1.0

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 CHANGED
@@ -15,3 +15,5 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ *~
19
+ nbproject/*
data/README.md CHANGED
@@ -1,6 +1,9 @@
1
1
  # RedundantColumn
2
2
 
3
- TODO: Write a gem description
3
+ Auto maintain the consistency of redundant column.
4
+
5
+ 1. Auto update redundant column.
6
+ 2. Auto fill redundant column value from redundant target object.
4
7
 
5
8
  ## Installation
6
9
 
@@ -18,7 +21,26 @@ Or install it yourself as:
18
21
 
19
22
  ## Usage
20
23
 
21
- TODO: Write usage instructions here
24
+ class User < ActiveRecord::Base
25
+ has_many :topics, :redundant_column => {:status => :user_status}
26
+ end
27
+
28
+ class Topic < ActiveRecord::Base
29
+ belongs_to :user, :redundant_column => {:user_status => :status}
30
+ end
31
+
32
+ user = User.create(:name => "Hooopo", :status => "active")
33
+
34
+ topic = Topic.create(:user => user, :title => "this is title")
35
+
36
+ assert_equal topic.user_status, user.status
37
+
38
+ user.status = "disable"
39
+ user.save
40
+
41
+ topic.reload
42
+
43
+ assert_equal topic.user_status, user.status
22
44
 
23
45
  ## Contributing
24
46
 
@@ -1,34 +1,3 @@
1
1
  require "redundant_column/version"
2
-
3
- module RedundantColumn
4
- def redundant_column(name, target_model, options = {})
5
- set_callback :update, :before, CallbackBuilder.new(name, target_model, options)
6
- end
7
-
8
- class CallbackBuilder
9
- attr_reader :name, :target_model, :target_name, :association_name
10
-
11
- def initialize(name, target_model, options = {})
12
- @name = name
13
- @target_model = target_model
14
- @target_name = options[:target_name]
15
- @association_name = options[:association_name] || "#{target_model.name.downcase.pluralize}"
16
- end
17
-
18
- def before_update(caller)
19
- if caller.send("#{name}_changed?")
20
- if caller.respond_to?(association_name)
21
- new_column_value = caller.send(name)
22
- target_name ||= "#{caller.class.name.downcase}_#{name}"
23
- update_sql = new_column_value.is_a?(String) ? %Q|#{target_name} = '#{new_column_value.gsub("'", "\\'")}'| : %Q|#{target_name} = #{new_column_value}|
24
- caller.send(association_name).update_all(update_sql)
25
- else
26
- STDERR.puts "You must set association in #{caller.class} model:"
27
- STDERR.puts "has_many :#{association_name}, ..."
28
- end
29
- end
30
- end
31
- end
32
- end
33
-
34
- ActiveRecord::Base.send :extend, RedundantColumn
2
+ require 'redundant_column/has_many'
3
+ require 'redundant_column/belongs_to'
@@ -0,0 +1,45 @@
1
+ module RedundantColumn
2
+ module BelongsTo
3
+ class CallbackBuilder
4
+ attr_reader :name, :target_name, :association_name
5
+
6
+ def initialize(name, target_name, association_name)
7
+ @name = name
8
+ @target_name = target_name
9
+ @association_name = association_name
10
+ end
11
+
12
+ def before_create(caller)
13
+ if caller.read_attribute(name).nil?
14
+ column_value = caller.send(association_name).try(target_name)
15
+ caller.send("#{name}=", column_value)
16
+ true
17
+ end
18
+ end
19
+ end
20
+
21
+ def self.included(base)
22
+ base.valid_options += [:redundant_column]
23
+ end
24
+
25
+ def build
26
+ reflection = super
27
+ add_counter_cache_callbacks(reflection) if options[:counter_cache]
28
+ add_touch_callbacks(reflection) if options[:touch]
29
+ configure_dependency
30
+ configure_auto_fill_redundant_column_callback
31
+ reflection
32
+ end
33
+
34
+ private
35
+
36
+ def configure_auto_fill_redundant_column_callback
37
+ if columns = options[:redundant_column]
38
+ column = columns.to_a.first
39
+ target_name = columns.to_a.last
40
+ model.set_callback :create, :before, CallbackBuilder.new(column, target_name, self.name)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ ActiveRecord::Associations::Builder::BelongsTo.send(:include, RedundantColumn::BelongsTo)
@@ -0,0 +1,62 @@
1
+ module RedundantColumn
2
+ module HasMany
3
+ class CallbackBuilder
4
+ attr_reader :name, :target_name, :association_name
5
+
6
+ def initialize(name, target_name, association_name)
7
+ @name = name
8
+ @target_name = target_name
9
+ @association_name = association_name
10
+ end
11
+
12
+ def before_update(caller)
13
+ if caller.send("#{name}_changed?")
14
+ if caller.respond_to?(association_name)
15
+ new_column_value = caller.send(name)
16
+
17
+ update_sql = if new_column_value.is_a?(String)
18
+ %Q|#{target_name} = '#{new_column_value.gsub("'", "\\'")}'|
19
+ else
20
+ %Q|#{target_name} = #{new_column_value}|
21
+ end
22
+ caller.send(association_name).update_all(update_sql)
23
+ else
24
+ STDERR.puts "You must set association in #{caller.class} model:"
25
+ STDERR.puts "has_many :#{association_name}, ..."
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+
32
+ def self.included(base)
33
+ base.valid_options += [:redundant_column]
34
+ end
35
+
36
+ def build
37
+ reflection = super
38
+ configure_dependency
39
+ configure_update_redundant_column_callback
40
+ reflection
41
+ end
42
+
43
+ private
44
+
45
+ def configure_update_redundant_column_callback
46
+ if columns = options[:redundant_column]
47
+ if columns.is_a?(Array)
48
+ columns.each do |column|
49
+ model.set_callback :update, :before, CallbackBuilder.new(column, model.name.downcase + "_#{column}", self.name)
50
+ end
51
+ elsif columns.is_a?(Hash)
52
+ columns.each do |column, target_name|
53
+ model.set_callback :update, :before, CallbackBuilder.new(column, target_name, self.name)
54
+ end
55
+ else
56
+ model.set_callback :update, :before, CallbackBuilder.new(column, model.name.downcase + "_#{columns}", self.name)
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ ActiveRecord::Associations::Builder::HasMany.send(:include, RedundantColumn::HasMany)
@@ -1,3 +1,3 @@
1
1
  module RedundantColumn
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redundant_column
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-02 00:00:00.000000000 Z
12
+ date: 2012-07-12 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: redundant column for activerecord
15
15
  email:
@@ -24,6 +24,8 @@ files:
24
24
  - README.md
25
25
  - Rakefile
26
26
  - lib/redundant_column.rb
27
+ - lib/redundant_column/belongs_to.rb
28
+ - lib/redundant_column/has_many.rb
27
29
  - lib/redundant_column/version.rb
28
30
  - redundant_column.gemspec
29
31
  homepage: ''