acts_as_relation 1.0.0 → 1.1.2

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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +5 -0
  4. data/Gemfile +2 -0
  5. data/Gemfile.lock +91 -62
  6. data/README.rdoc +28 -5
  7. data/Rakefile +1 -1
  8. data/acts_as_relation.gemspec +10 -10
  9. data/lib/active_record/acts_as_relation.rb +45 -126
  10. data/lib/active_record/acts_as_relation/access_methods.rb +63 -0
  11. data/lib/active_record/acts_as_relation/acts_as.rb +34 -0
  12. data/lib/active_record/acts_as_relation/acts_as_modules.rb +109 -0
  13. data/lib/active_record/acts_as_relation/superclass_migration.rb +32 -0
  14. data/lib/acts_as_relation.rb +4 -1
  15. data/lib/version.rb +1 -1
  16. data/spec/acts_as_relation_spec.rb +136 -59
  17. data/spec/acts_as_superclass_spec.rb +7 -7
  18. data/spec/dummy/app/models/product.rb +4 -0
  19. data/spec/dummy/app/models/store.rb +1 -0
  20. data/spec/dummy/config/application.rb +2 -49
  21. data/spec/dummy/config/boot.rb +1 -1
  22. data/spec/dummy/config/environments/development.rb +0 -3
  23. data/spec/dummy/config/environments/test.rb +1 -6
  24. data/spec/dummy/db/schema.rb +4 -0
  25. data/spec/spec_helper.rb +10 -7
  26. metadata +33 -73
  27. data/lib/active_record/acts_as_relation_superclass_migration.rb +0 -30
  28. data/spec/dummy/.rspec +0 -1
  29. data/spec/dummy/README.rdoc +0 -261
  30. data/spec/dummy/app/assets/javascripts/application.js +0 -15
  31. data/spec/dummy/app/assets/stylesheets/application.css +0 -13
  32. data/spec/dummy/app/controllers/application_controller.rb +0 -3
  33. data/spec/dummy/app/helpers/application_helper.rb +0 -2
  34. data/spec/dummy/app/mailers/.gitkeep +0 -0
  35. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  36. data/spec/dummy/config/environments/production.rb +0 -65
  37. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
  38. data/spec/dummy/config/initializers/inflections.rb +0 -15
  39. data/spec/dummy/config/initializers/mime_types.rb +0 -5
  40. data/spec/dummy/config/initializers/secret_token.rb +0 -7
  41. data/spec/dummy/config/initializers/session_store.rb +0 -8
  42. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
  43. data/spec/dummy/config/locales/en.yml +0 -5
  44. data/spec/dummy/config/routes.rb +0 -58
  45. data/spec/dummy/lib/assets/.gitkeep +0 -0
  46. data/spec/dummy/public/404.html +0 -26
  47. data/spec/dummy/public/422.html +0 -26
  48. data/spec/dummy/public/500.html +0 -25
  49. data/spec/dummy/public/favicon.ico +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a72ef528265e4e2439caa3e118c83ba0b8a0e236
4
- data.tar.gz: 9c1d9259eb36d2fe48dcd572ced40e1451e53ce0
3
+ metadata.gz: bc6b69987a960f143e2cf8b1b7fda99dd40bc1e4
4
+ data.tar.gz: 09eaed2afe535c9cf739db050575a0923cd1e80b
5
5
  SHA512:
6
- metadata.gz: b8e696a7fbeac93377ef709302730f00740274b7db2d13523e4f1735e1ca75f2f2507a623525a23d23dad0a11ac5bf296e1e5fee8986d4aa0255d71ced472aaa
7
- data.tar.gz: a181edf19a4b1f5fd9e73502323d691bfa5694fc6d1dddd2ca92445a55ae801a6169e9ce8e664d38c4e7364fcdd4021d5c922c9d22490db881756604642ce802
6
+ metadata.gz: d7ddfd42cd6f28d0d5a78819b92b7cbf9f64f72705a5f6b90d1ed541169304508d0990fb613840104b352e130622d44f68392e5a769291c045e3fa1ecb9839a6
7
+ data.tar.gz: f61af829ee9f54158e59ed5e3aa6e7b9da82c3ef3c44ae7999c383c4fcbfbd5e45b66f1efe645ba3996f7c94e5138b0cd3d76387be36d6688858b7de792e7def
data/.gitignore CHANGED
@@ -7,3 +7,4 @@ doc/*
7
7
  *.sqlite3
8
8
  *.log
9
9
  spec/dummy/tmp/*
10
+ coverage/*
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.1
4
+ - 2.0.0
5
+ - 1.9.3
data/Gemfile CHANGED
@@ -2,3 +2,5 @@ source "https://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in gemspec
4
4
  gemspec
5
+
6
+ gem 'coveralls', require: false
data/Gemfile.lock CHANGED
@@ -1,97 +1,125 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- acts_as_relation (1.0.0)
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.0.0)
11
- actionpack (= 4.0.0)
12
- mail (~> 2.5.3)
13
- actionpack (4.0.0)
14
- activesupport (= 4.0.0)
15
- builder (~> 3.1.0)
16
- erubis (~> 2.7.0)
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
- activemodel (4.0.0)
20
- activesupport (= 4.0.0)
21
- builder (~> 3.1.0)
22
- activerecord (4.0.0)
23
- activemodel (= 4.0.0)
24
- activerecord-deprecated_finders (~> 1.0.2)
25
- activesupport (= 4.0.0)
26
- arel (~> 4.0.0)
27
- activerecord-deprecated_finders (1.0.3)
28
- activesupport (4.0.0)
29
- i18n (~> 0.6, >= 0.6.4)
30
- minitest (~> 4.2)
31
- multi_json (~> 1.3)
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 (~> 0.3.37)
34
- arel (4.0.0)
35
- atomic (1.1.10)
36
- builder (3.1.4)
37
- database_cleaner (1.0.1)
38
- diff-lcs (1.2.4)
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.4)
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.23)
46
- minitest (4.7.5)
47
- multi_json (1.7.7)
48
- polyglot (0.3.3)
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.0.0)
53
- actionmailer (= 4.0.0)
54
- actionpack (= 4.0.0)
55
- activerecord (= 4.0.0)
56
- activesupport (= 4.0.0)
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.0.0)
59
- sprockets-rails (~> 2.0.0)
60
- railties (4.0.0)
61
- actionpack (= 4.0.0)
62
- activesupport (= 4.0.0)
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.1.0)
66
- rspec-core (2.13.1)
67
- rspec-expectations (2.13.0)
68
- diff-lcs (>= 1.1.3, < 2.0)
69
- rspec-mocks (2.13.1)
70
- rspec-rails (2.13.2)
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 (~> 2.13.0)
75
- rspec-expectations (~> 2.13.0)
76
- rspec-mocks (~> 2.13.0)
77
- sprockets (2.10.0)
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.0.0)
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.7)
87
- thor (0.18.1)
88
- thread_safe (0.1.0)
89
- atomic
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
- treetop (1.4.14)
117
+ tins (1.3.0)
118
+ treetop (1.4.15)
92
119
  polyglot
93
120
  polyglot (>= 0.3.1)
94
- tzinfo (0.3.37)
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
- Product.first.specific # will return a specific product, a pen for example
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
@@ -1,7 +1,7 @@
1
1
  require 'rake'
2
2
  require 'rspec/core/rake_task'
3
3
 
4
- task :default => :spec
4
+ task default: :spec
5
5
 
6
6
  desc 'Run specs'
7
7
  RSpec::Core::RakeTask.new
@@ -1,5 +1,5 @@
1
1
  # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path('../lib', __FILE__)
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 "rake"
27
- s.add_development_dependency "bundler"
28
- s.add_development_dependency "sqlite3"
29
- s.add_development_dependency "rspec-rails"
30
- s.add_development_dependency "rails"
31
- s.add_development_dependency "database_cleaner"
32
- s.add_dependency "activerecord"
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
- module AccessMethods
9
- protected
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
- if scope.is_a?(Hash)
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 "ActiveRecord::ActsAsModules::#{module_name}".constantize
113
- end
14
+ include ActiveRecord::ActsAsRelation::ActsAsModules[acts_as]
114
15
 
115
- if options.fetch :auto_join, true
116
- class_eval "default_scope -> { joins(:#{name}) }"
16
+ default_scope -> { includes(acts_as.name) }
117
17
  end
118
18
 
119
- class_eval "default_scope -> { includes(:#{name}) }"
19
+ class_eval { default_scope -> { joins(acts_as.name) } } if options.fetch :auto_join, true
120
20
 
121
- code = <<-EndCode
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
- :#{name}
27
+ "#{acts_as.name}".to_sym
128
28
  end
129
29
  EndCode
130
- instance_eval code, __FILE__, __LINE__
131
30
  end
132
- alias :is_a :acts_as
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
- def acts_as_superclass options={}
135
- association_name = options[:as] || acts_as_association_name
36
+ class_eval do
37
+ belongs_to association_name, polymorphic: true, dependent: :delete
136
38
 
137
- code = <<-EndCode
138
- belongs_to :#{association_name}, :polymorphic => true
39
+ alias_method :specific, association_name
40
+ alias_method :specific_class, :specific
139
41
 
140
- def specific
141
- self.#{association_name}
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
- alias :specific_class :specific
144
- EndCode
145
- class_eval code, __FILE__, __LINE__
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
- alias :is_a_superclass :acts_as_superclass
57
+ alias_method :is_a_superclass, :acts_as_superclass
148
58
 
149
- def acts_as_association_name model_name=nil
150
- model_name ||= self.name
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 ActiveRecord::Base
158
- include ActiveRecord::ActsAsRelation
75
+ class Base
76
+ include ActsAsRelation
77
+ end
159
78
  end