acts_as_relation 1.0.0 → 1.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +5 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +91 -62
- data/README.rdoc +28 -5
- data/Rakefile +1 -1
- data/acts_as_relation.gemspec +10 -10
- data/lib/active_record/acts_as_relation.rb +45 -126
- data/lib/active_record/acts_as_relation/access_methods.rb +63 -0
- data/lib/active_record/acts_as_relation/acts_as.rb +34 -0
- data/lib/active_record/acts_as_relation/acts_as_modules.rb +109 -0
- data/lib/active_record/acts_as_relation/superclass_migration.rb +32 -0
- data/lib/acts_as_relation.rb +4 -1
- data/lib/version.rb +1 -1
- data/spec/acts_as_relation_spec.rb +136 -59
- data/spec/acts_as_superclass_spec.rb +7 -7
- data/spec/dummy/app/models/product.rb +4 -0
- data/spec/dummy/app/models/store.rb +1 -0
- data/spec/dummy/config/application.rb +2 -49
- data/spec/dummy/config/boot.rb +1 -1
- data/spec/dummy/config/environments/development.rb +0 -3
- data/spec/dummy/config/environments/test.rb +1 -6
- data/spec/dummy/db/schema.rb +4 -0
- data/spec/spec_helper.rb +10 -7
- metadata +33 -73
- data/lib/active_record/acts_as_relation_superclass_migration.rb +0 -30
- data/spec/dummy/.rspec +0 -1
- data/spec/dummy/README.rdoc +0 -261
- data/spec/dummy/app/assets/javascripts/application.js +0 -15
- data/spec/dummy/app/assets/stylesheets/application.css +0 -13
- data/spec/dummy/app/controllers/application_controller.rb +0 -3
- data/spec/dummy/app/helpers/application_helper.rb +0 -2
- data/spec/dummy/app/mailers/.gitkeep +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +0 -14
- data/spec/dummy/config/environments/production.rb +0 -65
- data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/spec/dummy/config/initializers/inflections.rb +0 -15
- data/spec/dummy/config/initializers/mime_types.rb +0 -5
- data/spec/dummy/config/initializers/secret_token.rb +0 -7
- data/spec/dummy/config/initializers/session_store.rb +0 -8
- data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
- data/spec/dummy/config/locales/en.yml +0 -5
- data/spec/dummy/config/routes.rb +0 -58
- data/spec/dummy/lib/assets/.gitkeep +0 -0
- data/spec/dummy/public/404.html +0 -26
- data/spec/dummy/public/422.html +0 -26
- data/spec/dummy/public/500.html +0 -25
- data/spec/dummy/public/favicon.ico +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc6b69987a960f143e2cf8b1b7fda99dd40bc1e4
|
4
|
+
data.tar.gz: 09eaed2afe535c9cf739db050575a0923cd1e80b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d7ddfd42cd6f28d0d5a78819b92b7cbf9f64f72705a5f6b90d1ed541169304508d0990fb613840104b352e130622d44f68392e5a769291c045e3fa1ecb9839a6
|
7
|
+
data.tar.gz: f61af829ee9f54158e59ed5e3aa6e7b9da82c3ef3c44ae7999c383c4fcbfbd5e45b66f1efe645ba3996f7c94e5138b0cd3d76387be36d6688858b7de792e7def
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,97 +1,125 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
acts_as_relation (1.
|
5
|
-
activerecord
|
4
|
+
acts_as_relation (1.1.0)
|
5
|
+
activerecord (>= 3)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
actionmailer (4.
|
11
|
-
actionpack (= 4.
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
10
|
+
actionmailer (4.1.4)
|
11
|
+
actionpack (= 4.1.4)
|
12
|
+
actionview (= 4.1.4)
|
13
|
+
mail (~> 2.5.4)
|
14
|
+
actionpack (4.1.4)
|
15
|
+
actionview (= 4.1.4)
|
16
|
+
activesupport (= 4.1.4)
|
17
17
|
rack (~> 1.5.2)
|
18
18
|
rack-test (~> 0.6.2)
|
19
|
-
|
20
|
-
activesupport (= 4.
|
21
|
-
builder (~> 3.1
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
19
|
+
actionview (4.1.4)
|
20
|
+
activesupport (= 4.1.4)
|
21
|
+
builder (~> 3.1)
|
22
|
+
erubis (~> 2.7.0)
|
23
|
+
activemodel (4.1.4)
|
24
|
+
activesupport (= 4.1.4)
|
25
|
+
builder (~> 3.1)
|
26
|
+
activerecord (4.1.4)
|
27
|
+
activemodel (= 4.1.4)
|
28
|
+
activesupport (= 4.1.4)
|
29
|
+
arel (~> 5.0.0)
|
30
|
+
activesupport (4.1.4)
|
31
|
+
i18n (~> 0.6, >= 0.6.9)
|
32
|
+
json (~> 1.7, >= 1.7.7)
|
33
|
+
minitest (~> 5.1)
|
32
34
|
thread_safe (~> 0.1)
|
33
|
-
tzinfo (~>
|
34
|
-
arel (
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
35
|
+
tzinfo (~> 1.1)
|
36
|
+
arel (5.0.1.20140414130214)
|
37
|
+
builder (3.2.2)
|
38
|
+
coveralls (0.7.0)
|
39
|
+
multi_json (~> 1.3)
|
40
|
+
rest-client
|
41
|
+
simplecov (>= 0.7)
|
42
|
+
term-ansicolor
|
43
|
+
thor
|
44
|
+
database_cleaner (1.3.0)
|
45
|
+
diff-lcs (1.2.5)
|
46
|
+
docile (1.1.5)
|
39
47
|
erubis (2.7.0)
|
40
48
|
hike (1.2.3)
|
41
|
-
i18n (0.6.
|
49
|
+
i18n (0.6.11)
|
50
|
+
json (1.8.1)
|
42
51
|
mail (2.5.4)
|
43
52
|
mime-types (~> 1.16)
|
44
53
|
treetop (~> 1.4.8)
|
45
|
-
mime-types (1.
|
46
|
-
minitest (4.
|
47
|
-
multi_json (1.
|
48
|
-
|
54
|
+
mime-types (1.25.1)
|
55
|
+
minitest (5.4.0)
|
56
|
+
multi_json (1.10.1)
|
57
|
+
netrc (0.7.7)
|
58
|
+
polyglot (0.3.5)
|
49
59
|
rack (1.5.2)
|
50
60
|
rack-test (0.6.2)
|
51
61
|
rack (>= 1.0)
|
52
|
-
rails (4.
|
53
|
-
actionmailer (= 4.
|
54
|
-
actionpack (= 4.
|
55
|
-
|
56
|
-
|
62
|
+
rails (4.1.4)
|
63
|
+
actionmailer (= 4.1.4)
|
64
|
+
actionpack (= 4.1.4)
|
65
|
+
actionview (= 4.1.4)
|
66
|
+
activemodel (= 4.1.4)
|
67
|
+
activerecord (= 4.1.4)
|
68
|
+
activesupport (= 4.1.4)
|
57
69
|
bundler (>= 1.3.0, < 2.0)
|
58
|
-
railties (= 4.
|
59
|
-
sprockets-rails (~> 2.0
|
60
|
-
railties (4.
|
61
|
-
actionpack (= 4.
|
62
|
-
activesupport (= 4.
|
70
|
+
railties (= 4.1.4)
|
71
|
+
sprockets-rails (~> 2.0)
|
72
|
+
railties (4.1.4)
|
73
|
+
actionpack (= 4.1.4)
|
74
|
+
activesupport (= 4.1.4)
|
63
75
|
rake (>= 0.8.7)
|
64
76
|
thor (>= 0.18.1, < 2.0)
|
65
|
-
rake (10.
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
rspec-
|
70
|
-
|
77
|
+
rake (10.3.2)
|
78
|
+
rest-client (1.7.1)
|
79
|
+
mime-types (>= 1.16, < 3.0)
|
80
|
+
netrc (~> 0.7)
|
81
|
+
rspec-core (3.0.2)
|
82
|
+
rspec-support (~> 3.0.0)
|
83
|
+
rspec-expectations (3.0.2)
|
84
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
85
|
+
rspec-support (~> 3.0.0)
|
86
|
+
rspec-mocks (3.0.2)
|
87
|
+
rspec-support (~> 3.0.0)
|
88
|
+
rspec-rails (3.0.1)
|
71
89
|
actionpack (>= 3.0)
|
72
90
|
activesupport (>= 3.0)
|
73
91
|
railties (>= 3.0)
|
74
|
-
rspec-core (~>
|
75
|
-
rspec-expectations (~>
|
76
|
-
rspec-mocks (~>
|
77
|
-
|
92
|
+
rspec-core (~> 3.0.0)
|
93
|
+
rspec-expectations (~> 3.0.0)
|
94
|
+
rspec-mocks (~> 3.0.0)
|
95
|
+
rspec-support (~> 3.0.0)
|
96
|
+
rspec-support (3.0.2)
|
97
|
+
simplecov (0.8.2)
|
98
|
+
docile (~> 1.1.0)
|
99
|
+
multi_json
|
100
|
+
simplecov-html (~> 0.8.0)
|
101
|
+
simplecov-html (0.8.0)
|
102
|
+
sprockets (2.12.1)
|
78
103
|
hike (~> 1.2)
|
79
104
|
multi_json (~> 1.0)
|
80
105
|
rack (~> 1.0)
|
81
106
|
tilt (~> 1.1, != 1.3.0)
|
82
|
-
sprockets-rails (2.
|
107
|
+
sprockets-rails (2.1.3)
|
83
108
|
actionpack (>= 3.0)
|
84
109
|
activesupport (>= 3.0)
|
85
110
|
sprockets (~> 2.8)
|
86
|
-
sqlite3 (1.3.
|
87
|
-
|
88
|
-
|
89
|
-
|
111
|
+
sqlite3 (1.3.9)
|
112
|
+
term-ansicolor (1.3.0)
|
113
|
+
tins (~> 1.0)
|
114
|
+
thor (0.19.1)
|
115
|
+
thread_safe (0.3.4)
|
90
116
|
tilt (1.4.1)
|
91
|
-
|
117
|
+
tins (1.3.0)
|
118
|
+
treetop (1.4.15)
|
92
119
|
polyglot
|
93
120
|
polyglot (>= 0.3.1)
|
94
|
-
tzinfo (
|
121
|
+
tzinfo (1.2.1)
|
122
|
+
thread_safe (~> 0.1)
|
95
123
|
|
96
124
|
PLATFORMS
|
97
125
|
ruby
|
@@ -99,8 +127,9 @@ PLATFORMS
|
|
99
127
|
DEPENDENCIES
|
100
128
|
acts_as_relation!
|
101
129
|
bundler
|
130
|
+
coveralls
|
102
131
|
database_cleaner
|
103
|
-
rails
|
132
|
+
rails (>= 3)
|
104
133
|
rake
|
105
|
-
rspec-rails
|
134
|
+
rspec-rails (>= 2.14)
|
106
135
|
sqlite3
|
data/README.rdoc
CHANGED
@@ -1,10 +1,14 @@
|
|
1
|
+
{<img src="https://travis-ci.org/hzamani/acts_as_relation.svg?branch=master" alt="Build Status" />}[https://travis-ci.org/hzamani/acts_as_relation]
|
2
|
+
{<img src="https://coveralls.io/repos/hzamani/acts_as_relation/badge.png?branch=master" alt="Coverage Status" />}[https://coveralls.io/r/hzamani/acts_as_relation?branch=master]
|
3
|
+
{<img src="https://codeclimate.com/github/hzamani/acts_as_relation.png" />}[https://codeclimate.com/github/hzamani/acts_as_relation]
|
4
|
+
|
1
5
|
= ActsAsRelation
|
2
6
|
This gem helps implement multiple-table-inheritance (MTI) methods to your ActiveRecord models.
|
3
7
|
By default, ActiveRecord only supports single-table inheritance (STI).
|
4
8
|
MTI gives you the benefits of STI but without having to place dozens of empty fields into a single table.
|
5
9
|
|
6
|
-
Take a traditional e-commerce application for example...
|
7
|
-
A product has common attributes (+name+, +price+, +image+ ...),
|
10
|
+
Take a traditional e-commerce application for example...
|
11
|
+
A product has common attributes (+name+, +price+, +image+ ...),
|
8
12
|
while each type of product has its own attributes...
|
9
13
|
+pen+ has +color+, +book+ has +author+ and +publisher+ and so on.
|
10
14
|
|
@@ -18,7 +22,7 @@ If you are using Rails 3 you must use '~> 0.1' version specifier in Gemfile.
|
|
18
22
|
|
19
23
|
== Usage
|
20
24
|
+acts_as_relation+ uses a polymorphic +has_one+
|
21
|
-
association to simulate multiple-table inheritance.
|
25
|
+
association to simulate multiple-table inheritance.
|
22
26
|
For the e-commerce example you would declare the product as a +supermodel+ and all types of it as +acts_as+ +:product+
|
23
27
|
(if you prefer you can use their aliases +is_a+ and +is_a_superclass+)
|
24
28
|
|
@@ -34,6 +38,10 @@ For the e-commerce example you would declare the product as a +supermodel+ and a
|
|
34
38
|
acts_as :product
|
35
39
|
end
|
36
40
|
|
41
|
+
class Store < ActiveRecord::Base
|
42
|
+
has_many :products
|
43
|
+
end
|
44
|
+
|
37
45
|
To make this work, you need to declare both a foreign key column and a type column
|
38
46
|
in the model that declares superclass. To do this you can set +:as_relation_superclass+
|
39
47
|
option to +true+ on +products+ +create_table+ (or pass it name of the association):
|
@@ -43,17 +51,25 @@ option to +true+ on +products+ +create_table+ (or pass it name of the associatio
|
|
43
51
|
end
|
44
52
|
|
45
53
|
Or declare them as you do on a +polymorphic+ +belongs_to+ association, it this case
|
46
|
-
you must pass name to +acts_as+ in +:as+ option:
|
54
|
+
you must pass name to +acts_as+ and +acts_as_superclass+ in +:as+ option:
|
47
55
|
|
48
56
|
change_table :products do |t|
|
49
57
|
t.integer :producible_id
|
50
58
|
t.string :producible_type
|
51
59
|
end
|
52
60
|
|
61
|
+
class Product < ActiveRecord::Base
|
62
|
+
acts_as_superclass :as => :producible
|
63
|
+
end
|
64
|
+
|
53
65
|
class Pen < ActiveRecord::Base
|
54
66
|
acts_as :product, :as => :producible
|
55
67
|
end
|
56
68
|
|
69
|
+
class Book < ActiveRecord::Base
|
70
|
+
acts_as :product, :as => :producible
|
71
|
+
end
|
72
|
+
|
57
73
|
Now +Pen+ and +Book+ *act* *as* +Product+. This means that they inherit +Product+
|
58
74
|
_attributes_, _associations_, _validations_ and _methods_.
|
59
75
|
|
@@ -81,7 +97,13 @@ methods (includeing accessors) so you can access them directly.
|
|
81
97
|
|
82
98
|
On the other hand you can always access a specific object from its parent by calling +specific+ method on it:
|
83
99
|
|
84
|
-
|
100
|
+
Product.first.specific # will return a specific product, a pen for example
|
101
|
+
|
102
|
+
In +has_many+ case you can use subclasses:
|
103
|
+
|
104
|
+
store = Store.create
|
105
|
+
store.products << Pen.create
|
106
|
+
store.products.first # => <Pen: ...>
|
85
107
|
|
86
108
|
== Options
|
87
109
|
The +acts_as+ relation support these options:
|
@@ -106,4 +128,5 @@ Note that support for +:conditions+ and +:include+ has been removed. In their pl
|
|
106
128
|
+where()+ and +includes()+:
|
107
129
|
|
108
130
|
acts_as :product, -> { where(color: "yellow") }
|
131
|
+
acts_as :person, -> { includes(:friends) }
|
109
132
|
|
data/Rakefile
CHANGED
data/acts_as_relation.gemspec
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
|
2
|
+
$LOAD_PATH.push File.expand_path('../lib', __FILE__)
|
3
3
|
require 'version'
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
@@ -14,20 +14,20 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.summary = 'Easy multi-table inheritance for rails'
|
15
15
|
s.description = "This 'acts_as' extension provides multi-table inheritance for rails models."
|
16
16
|
|
17
|
-
|
18
17
|
# Load Paths...
|
19
18
|
s.files = `git ls-files`.split("\n")
|
20
19
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
21
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
22
21
|
s.require_paths = ['lib']
|
23
22
|
|
23
|
+
s.required_ruby_version = '>= 1.9'
|
24
24
|
|
25
25
|
# Dependencies (installed via 'bundle install')...
|
26
|
-
s.add_development_dependency
|
27
|
-
s.add_development_dependency
|
28
|
-
s.add_development_dependency
|
29
|
-
s.add_development_dependency
|
30
|
-
s.add_development_dependency
|
31
|
-
s.add_development_dependency
|
32
|
-
s.add_dependency
|
26
|
+
s.add_development_dependency 'rake'
|
27
|
+
s.add_development_dependency 'bundler'
|
28
|
+
s.add_development_dependency 'sqlite3'
|
29
|
+
s.add_development_dependency 'rspec-rails', '~> 2.14'
|
30
|
+
s.add_development_dependency 'rails', '~> 4.0'
|
31
|
+
s.add_development_dependency 'database_cleaner'
|
32
|
+
s.add_dependency 'activerecord', '~> 4.0'
|
33
33
|
end
|
@@ -1,159 +1,78 @@
|
|
1
1
|
module ActiveRecord
|
2
|
-
|
3
|
-
module ActsAsModules end
|
4
|
-
|
5
2
|
module ActsAsRelation
|
6
3
|
extend ActiveSupport::Concern
|
7
4
|
|
8
|
-
|
9
|
-
|
10
|
-
def define_acts_as_accessors(attribs, model_name)
|
11
|
-
attribs.each do |attrib|
|
12
|
-
code = <<-EndCode
|
13
|
-
def #{attrib}
|
14
|
-
#{model_name}.#{attrib}
|
15
|
-
end
|
16
|
-
|
17
|
-
def #{attrib}=(value)
|
18
|
-
#{model_name}.#{attrib} = value
|
19
|
-
end
|
20
|
-
|
21
|
-
def #{attrib}?
|
22
|
-
#{model_name}.#{attrib}?
|
23
|
-
end
|
24
|
-
EndCode
|
25
|
-
class_eval code, __FILE__, __LINE__
|
26
|
-
end
|
27
|
-
end
|
5
|
+
included do
|
6
|
+
alias_method :acts_as?, :is_a?
|
28
7
|
end
|
29
8
|
|
30
9
|
module ClassMethods
|
31
|
-
def acts_as(model_name, scope=nil, options={})
|
32
|
-
|
33
|
-
options = scope
|
34
|
-
scope = nil
|
35
|
-
end
|
36
|
-
|
37
|
-
if options[:conditions]
|
38
|
-
ActiveSupport::Deprecation.warn(":conditions is no longer supported by acts_as. Please use `where()` instead. Example: `acts_as :person, -> { where(name: 'John') }`")
|
39
|
-
end
|
40
|
-
if options[:include]
|
41
|
-
ActiveSupport::Deprecation.warn(":include is no longer supported by acts_as. Please use `includes()` instead. Example: `acts_as :person, -> { includes(:friends) }`")
|
42
|
-
end
|
43
|
-
|
44
|
-
name = model_name.to_s.underscore.singularize
|
45
|
-
class_name = options[:class_name] || name.camelcase
|
46
|
-
association_name = options[:as] || acts_as_association_name(name)
|
47
|
-
module_name = "ActsAs#{name.camelcase}"
|
48
|
-
|
49
|
-
unless ActiveRecord::ActsAsModules.const_defined? module_name
|
50
|
-
# Create ActsAsModel module
|
51
|
-
acts_as_model = Module.new
|
52
|
-
ActiveRecord::ActsAsModules.const_set(module_name, acts_as_model)
|
53
|
-
|
54
|
-
has_one_options = {
|
55
|
-
:as => association_name,
|
56
|
-
:class_name => class_name,
|
57
|
-
:autosave => true,
|
58
|
-
:validate => false,
|
59
|
-
:dependent => options.fetch(:dependent, :destroy),
|
60
|
-
}
|
61
|
-
|
62
|
-
acts_as_model.module_eval do
|
63
|
-
singleton = class << self ; self end
|
64
|
-
singleton.send :define_method, :included do |base|
|
65
|
-
base.has_one name.to_sym, scope, has_one_options
|
66
|
-
base.validate "#{name}_must_be_valid".to_sym
|
67
|
-
base.alias_method_chain name.to_sym, :autobuild
|
68
|
-
|
69
|
-
base.extend ActiveRecord::ActsAsRelation::AccessMethods
|
70
|
-
attributes = class_name.constantize.content_columns.map(&:name)
|
71
|
-
associations = class_name.constantize.reflect_on_all_associations.map(&:name)
|
72
|
-
ignored = ["created_at", "updated_at", "#{association_name}_id", "#{association_name}_type", "#{association_name}"]
|
73
|
-
attributes_to_delegate = attributes + associations - ignored
|
74
|
-
base.send :define_acts_as_accessors, attributes_to_delegate, name
|
75
|
-
|
76
|
-
if defined?(::ProtectedAttributes)
|
77
|
-
base.attr_accessible.update(class_name.constantize.attr_accessible)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
define_method "#{name}_with_autobuild" do
|
82
|
-
send("#{name}_without_autobuild") || send("build_#{name}")
|
83
|
-
end
|
84
|
-
|
85
|
-
define_method :method_missing do |method, *arg, &block|
|
86
|
-
begin
|
87
|
-
raise NoMethodError if method.to_s == 'id' || method.to_s == name
|
88
|
-
|
89
|
-
send(name).send(method, *arg, &block)
|
90
|
-
rescue NoMethodError
|
91
|
-
super(method, *arg, &block)
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
define_method 'respond_to?' do |method, include_private_methods = false|
|
96
|
-
super(method, include_private_methods) || send(name).respond_to?(method, include_private_methods)
|
97
|
-
end
|
98
|
-
|
99
|
-
protected
|
100
|
-
|
101
|
-
define_method "#{name}_must_be_valid" do
|
102
|
-
unless send(name).valid?
|
103
|
-
send(name).errors.each do |att, message|
|
104
|
-
errors.add(att, message)
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
10
|
+
def acts_as(model_name, scope = nil, options = {})
|
11
|
+
acts_as = ActsAs.new(model_name, scope, options)
|
110
12
|
|
111
13
|
class_eval do
|
112
|
-
include
|
113
|
-
end
|
14
|
+
include ActiveRecord::ActsAsRelation::ActsAsModules[acts_as]
|
114
15
|
|
115
|
-
|
116
|
-
class_eval "default_scope -> { joins(:#{name}) }"
|
16
|
+
default_scope -> { includes(acts_as.name) }
|
117
17
|
end
|
118
18
|
|
119
|
-
class_eval
|
19
|
+
class_eval { default_scope -> { joins(acts_as.name) } } if options.fetch :auto_join, true
|
120
20
|
|
121
|
-
|
21
|
+
instance_eval <<-EndCode, __FILE__, __LINE__ + 1
|
122
22
|
def acts_as_other_model?
|
123
23
|
true
|
124
24
|
end
|
125
25
|
|
126
26
|
def acts_as_model_name
|
127
|
-
|
27
|
+
"#{acts_as.name}".to_sym
|
128
28
|
end
|
129
29
|
EndCode
|
130
|
-
instance_eval code, __FILE__, __LINE__
|
131
30
|
end
|
132
|
-
|
31
|
+
alias_method :is_a, :acts_as
|
32
|
+
|
33
|
+
def acts_as_superclass(options = {})
|
34
|
+
association_name = (options[:as] || acts_as_association_name).to_sym
|
133
35
|
|
134
|
-
|
135
|
-
|
36
|
+
class_eval do
|
37
|
+
belongs_to association_name, polymorphic: true, dependent: :delete
|
136
38
|
|
137
|
-
|
138
|
-
|
39
|
+
alias_method :specific, association_name
|
40
|
+
alias_method :specific_class, :specific
|
139
41
|
|
140
|
-
def
|
141
|
-
|
42
|
+
def method_missing(method, *arg, &block)
|
43
|
+
if specific && specific.respond_to?(method)
|
44
|
+
specific.send(method, *arg, &block)
|
45
|
+
else
|
46
|
+
super
|
47
|
+
end
|
142
48
|
end
|
143
|
-
|
144
|
-
|
145
|
-
|
49
|
+
|
50
|
+
def is_a?(klass)
|
51
|
+
(specific && specific.class == klass) ? true : super
|
52
|
+
end
|
53
|
+
alias_method :instance_of?, :is_a?
|
54
|
+
alias_method :kind_of?, :is_a?
|
55
|
+
end
|
146
56
|
end
|
147
|
-
|
57
|
+
alias_method :is_a_superclass, :acts_as_superclass
|
148
58
|
|
149
|
-
def
|
150
|
-
|
59
|
+
def is_a?(klass)
|
60
|
+
if respond_to?(:acts_as_model_name) && acts_as_model_name == klass.name.downcase.to_sym
|
61
|
+
true
|
62
|
+
else
|
63
|
+
super
|
64
|
+
end
|
65
|
+
end
|
66
|
+
alias_method :acts_as?, :is_a?
|
67
|
+
|
68
|
+
def acts_as_association_name(model_name = nil)
|
69
|
+
model_name ||= name
|
151
70
|
"as_#{model_name.to_s.demodulize.singularize.underscore}"
|
152
71
|
end
|
153
72
|
end
|
154
73
|
end
|
155
|
-
end
|
156
74
|
|
157
|
-
class
|
158
|
-
|
75
|
+
class Base
|
76
|
+
include ActsAsRelation
|
77
|
+
end
|
159
78
|
end
|