activerecord_null_object 0.1.0 → 0.2.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/VERSION +1 -1
- data/activerecord_null_object.gemspec +1 -1
- data/init.rb +1 -1
- data/lib/activerecord_null_object.rb +41 -29
- data/spec/schema.rb +21 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +19 -1
- metadata +1 -1
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/init.rb
CHANGED
@@ -2,6 +2,35 @@ module ActiveRecord
|
|
2
2
|
module Associations
|
3
3
|
module ClassMethods
|
4
4
|
|
5
|
+
# Add null object support to the given accessor method.
|
6
|
+
def add_null_object_support(association_id, options = {}) #:nodoc:
|
7
|
+
# Determine the class of the association.
|
8
|
+
association_class_name = options[:class_name] || association_id.to_s.classify
|
9
|
+
association_class = association_class_name.constantize
|
10
|
+
|
11
|
+
# Determine the null class for this association.
|
12
|
+
null_class_name = "Null" + association_class_name
|
13
|
+
if Object.const_defined?(null_class_name)
|
14
|
+
null_class = Object.const_get(null_class_name.to_sym)
|
15
|
+
else
|
16
|
+
# Define the null class as an ancestor of the association class.
|
17
|
+
null_class = Object.const_set(null_class_name, Class.new(association_class))
|
18
|
+
null_class.class_eval do
|
19
|
+
include Singleton
|
20
|
+
include ActiveRecordNullObject::NullObject
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Modify the "getter" of the relationship to return an
|
25
|
+
# instance of the association's null object instead of returning nil.
|
26
|
+
class_eval do
|
27
|
+
define_method("#{association_id}_with_null_object".to_sym) do
|
28
|
+
send("#{association_id}_without_null_object".to_sym) || null_class.instance
|
29
|
+
end
|
30
|
+
alias_method_chain association_id, :null_object
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
5
34
|
# Add a boolean :null_object option to belongs_to.
|
6
35
|
def belongs_to_with_null_object(association_id, options = {}) #:nodoc:
|
7
36
|
# Extract our custom option.
|
@@ -9,37 +38,20 @@ module ActiveRecord
|
|
9
38
|
# Call the real belongs_to so that the association gets defined.
|
10
39
|
belongs_to_without_null_object(association_id, options)
|
11
40
|
# Modify the association if need be.
|
12
|
-
if use_null_object
|
13
|
-
|
14
|
-
# Determine the class of the association.
|
15
|
-
association_class_name = options[:class_name] || association_id.to_s.classify
|
16
|
-
association_class = association_class_name.constantize
|
17
|
-
|
18
|
-
# Determine the null class for this association.
|
19
|
-
null_class_name = "Null" + association_class_name
|
20
|
-
if Object.const_defined?(null_class_name)
|
21
|
-
null_class = Object.const_get(null_class_name.to_sym)
|
22
|
-
else
|
23
|
-
# Define the null class as an ancestor of the association class.
|
24
|
-
null_class = Object.const_set(null_class_name, Class.new(association_class))
|
25
|
-
null_class.class_eval do
|
26
|
-
include Singleton
|
27
|
-
include ActiveRecordNullObject::NullObject
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
# Modify the "getter" of the belongs_to relationship to return an
|
32
|
-
# instance of the association's null object instead of returning nil.
|
33
|
-
class_eval do
|
34
|
-
define_method("#{association_id}_with_null_object".to_sym) do
|
35
|
-
send("#{association_id}_without_null_object".to_sym) || null_class.instance
|
36
|
-
end
|
37
|
-
alias_method_chain association_id, :null_object
|
38
|
-
end
|
39
|
-
|
40
|
-
end
|
41
|
+
add_null_object_support(association_id, options) if use_null_object
|
41
42
|
end
|
42
43
|
alias_method_chain :belongs_to, :null_object
|
44
|
+
|
45
|
+
# Add a boolean :null_object option to has_one.
|
46
|
+
def has_one_with_null_object(association_id, options = {}) #:nodoc:
|
47
|
+
# Extract our custom option.
|
48
|
+
use_null_object = options.delete(:null_object)
|
49
|
+
# Call the real has_one so that the association gets defined.
|
50
|
+
has_one_without_null_object(association_id, options)
|
51
|
+
# Modify the association if need be.
|
52
|
+
add_null_object_support(association_id, options) if use_null_object
|
53
|
+
end
|
54
|
+
alias_method_chain :has_one, :null_object
|
43
55
|
|
44
56
|
end
|
45
57
|
end
|
data/spec/schema.rb
CHANGED
@@ -5,6 +5,27 @@ ActiveRecord::Schema.define(:version => 0) do
|
|
5
5
|
t.datetime "updated_at"
|
6
6
|
end
|
7
7
|
|
8
|
+
create_table "accounts", :force => true do |t|
|
9
|
+
t.integer "author_id"
|
10
|
+
t.string "password"
|
11
|
+
t.datetime "created_at"
|
12
|
+
t.datetime "updated_at"
|
13
|
+
end
|
14
|
+
|
15
|
+
create_table "addresses", :force => true do |t|
|
16
|
+
t.integer "author_id"
|
17
|
+
t.string "street"
|
18
|
+
t.datetime "created_at"
|
19
|
+
t.datetime "updated_at"
|
20
|
+
end
|
21
|
+
|
22
|
+
create_table "profiles", :force => true do |t|
|
23
|
+
t.integer "author_id"
|
24
|
+
t.integer "age"
|
25
|
+
t.datetime "created_at"
|
26
|
+
t.datetime "updated_at"
|
27
|
+
end
|
28
|
+
|
8
29
|
create_table "comments", :force => true do |t|
|
9
30
|
t.text "body"
|
10
31
|
t.integer "author_id"
|
data/spec/spec.opts
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
require '
|
2
|
+
require 'active_record'
|
3
3
|
require 'yaml'
|
4
4
|
require 'spec'
|
5
5
|
require File.dirname(__FILE__) + '/../init.rb'
|
@@ -9,11 +9,28 @@ config = YAML::load(File.open(File.dirname(__FILE__) + '/database.yml'))
|
|
9
9
|
ActiveRecord::Base.establish_connection(config['test'])
|
10
10
|
load(File.dirname(__FILE__) + "/schema.rb")
|
11
11
|
|
12
|
+
# Fixes 'address'.singularize # => 'addres'
|
13
|
+
ActiveSupport::Inflector.inflections do |inflect|
|
14
|
+
inflect.singular(/ess$/i, 'ess')
|
15
|
+
end
|
16
|
+
|
17
|
+
class Account < ActiveRecord::Base
|
18
|
+
end
|
19
|
+
|
20
|
+
class Address < ActiveRecord::Base
|
21
|
+
end
|
22
|
+
|
23
|
+
class Profile < ActiveRecord::Base
|
24
|
+
end
|
25
|
+
|
12
26
|
# Define ActiveRecord classes to use while testing.
|
13
27
|
class Author < ActiveRecord::Base
|
14
28
|
has_many :posts
|
15
29
|
has_many :comments
|
16
30
|
has_many :sessions
|
31
|
+
has_one :profile
|
32
|
+
has_one :account, :null_object => false
|
33
|
+
has_one :address, :null_object => true
|
17
34
|
end
|
18
35
|
|
19
36
|
class Comment < ActiveRecord::Base
|
@@ -27,3 +44,4 @@ end
|
|
27
44
|
class Session < ActiveRecord::Base
|
28
45
|
belongs_to :author
|
29
46
|
end
|
47
|
+
|