redundant_column 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: ''