multi_tabular 0.0.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.
- checksums.yaml +7 -0
- data/Gemfile +4 -0
- data/lib/multi_tabular.rb +9 -0
- data/lib/multi_tabular/references.rb +91 -0
- data/lib/multi_tabular/sub.rb +13 -0
- data/lib/multi_tabular/super.rb +18 -0
- data/lib/multi_tabular/version.rb +3 -0
- metadata +79 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 92cbe3c16e1fc9900bea20bb3639e58ebc986ba3
|
|
4
|
+
data.tar.gz: 4c0b92455f9d66494462fae3df726388f77144b2
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 507ccebc9e858d9dc1ef6369eddc49d0cd25840c64e90120fa91c11c6ecf5e9e54fd231bec76394ed5791fc6a02ece1eed7d2ab1cf438f836faf976847965e85
|
|
7
|
+
data.tar.gz: b3e5d0b1702d0a503c748ac62192889859bf9fe48131215f8642ec83757f0474f4c9955221b82cdc57dd466c18781e1c1c4abd61cf02349da10b6866ea6f8551
|
data/Gemfile
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
module MultiTabular
|
|
2
|
+
# For classes that reference an MTI class
|
|
3
|
+
module References
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
|
|
6
|
+
included do
|
|
7
|
+
def reflection_assignment_method(klass)
|
|
8
|
+
self.class.reflect_on_association(reflection_symbol(klass)).name.to_s + '='
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def reflection_assignment_symbol(sym)
|
|
12
|
+
self.class.reflect_on_association(sym).name.to_s + '='
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# for all subclasses of the given base class, returns a
|
|
16
|
+
# list of defined associations within the current class
|
|
17
|
+
def association_methods(mti_base_class)
|
|
18
|
+
(mti_base_class.descendants << mti_base_class).map{|s|
|
|
19
|
+
assoc = self.class.reflect_on_association(reflection_symbol s)
|
|
20
|
+
assoc ? assoc.name : nil
|
|
21
|
+
}.compact
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# for a given class, returns the appropriate symbol
|
|
25
|
+
# to pass to the ActiveRecord method reflect_on_association
|
|
26
|
+
def reflection_symbol(klass)
|
|
27
|
+
klass.to_s.sub('::', '_').underscore.to_sym
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
module ClassMethods
|
|
32
|
+
# create a polymorphic association to an MTI construct in a belongs_to fashion,
|
|
33
|
+
# meaning that the table of the class including this mixin has a foreign key to each of the MTI construct's
|
|
34
|
+
# concrete models. It defines a getter and setter method named like the assoc_sym argument.
|
|
35
|
+
# The method tries to guess the base class itself based on the association name, but if namespaces or an arbitrary
|
|
36
|
+
# association name is used, the name of the base class should be passed as string with base_class: 'BaseClassName"
|
|
37
|
+
def belongs_to_mti(assoc_sym, params = {})
|
|
38
|
+
# Check if guessed or passed in constant is a class and is a descendant of ActiveRecord::Base
|
|
39
|
+
def validate_base_class(bc)
|
|
40
|
+
bc.is_a?(Class) && bc < ActiveRecord::Base
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# for a given class, returns the appropriate symbol
|
|
44
|
+
# to pass to the ActiveRecord method reflect_on_association
|
|
45
|
+
def reflection_symbol(klass)
|
|
46
|
+
klass.to_s.sub('::', '_').underscore.to_sym
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
if params.key? :base_class
|
|
50
|
+
base_class = Module.const_get params[:base_class]
|
|
51
|
+
else
|
|
52
|
+
base_class = Module.const_get assoc_sym.capitalize
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Raise an error if the base class doesn't saturate the conditions.
|
|
56
|
+
unless validate_base_class base_class
|
|
57
|
+
fail InvalidBaseClassError.new "#{base_class} is not a valid base class."
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Define the getter method for retrieving a referenced MTI record.
|
|
61
|
+
# Each association method for the base class is invoked and first that returns a result will be used.
|
|
62
|
+
define_method(assoc_sym.to_s) do
|
|
63
|
+
association_methods(base_class).map do|a|
|
|
64
|
+
send a
|
|
65
|
+
end.reduce do |a, b|
|
|
66
|
+
a || b
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
define_method("count_#{assoc_sym.to_s.pluralize}") do
|
|
71
|
+
association_methods(base_class).reduce(0) do |sum, method|
|
|
72
|
+
send(method) ? sum + 1 : sum
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Define the setter method that dynamically accesses the concrete setter for the type of the assignee.
|
|
77
|
+
define_method("#{assoc_sym}=") do |assignee|
|
|
78
|
+
association_methods(base_class).each do |association|
|
|
79
|
+
send reflection_assignment_symbol(association), nil
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
send reflection_assignment_method(assignee.class), assignee
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
class ActiveRecord::Base
|
|
90
|
+
include MultiTabular::References
|
|
91
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module MultiTabular
|
|
2
|
+
# For subclasses of an MTI construct.
|
|
3
|
+
# These classes inherit logic from a superclass and are persisted in their own table.
|
|
4
|
+
module Sub
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
# Set the table name to be the class name, including namespaces.
|
|
8
|
+
# If a different table should be used, override this variable in your class.
|
|
9
|
+
included do
|
|
10
|
+
self.table_name = name.underscore.sub('/', '_').pluralize
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module MultiTabular
|
|
2
|
+
# For superclasses of an MTI construct.
|
|
3
|
+
# These classes can provide shared logic, but are not an activerecord-model on their own,
|
|
4
|
+
# meaning they have no corresponding table in the database.
|
|
5
|
+
module Super
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
included do
|
|
9
|
+
self.abstract_class = true
|
|
10
|
+
|
|
11
|
+
# Allow converting the class name to an assumed foreign key in an associated model's database.
|
|
12
|
+
# If a different foreign should be used, you can override this method or simply declare the foreign key manually.
|
|
13
|
+
def self.to_foreign_key
|
|
14
|
+
name.underscore.sub('/', '_').singularize << '_id'
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: multi_tabular
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.2
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Alexander Junger
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2015-02-19 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: activesupport
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '4.1'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '4.1'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: activerecord
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '4.1'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '4.1'
|
|
41
|
+
description: |-
|
|
42
|
+
Facilitates true multi table inheritance of ActiveRecord models by providing methods for
|
|
43
|
+
super- and subclasses as well as models with a foreign-key association to MTI records.
|
|
44
|
+
email: hello@alexanderjunger.at
|
|
45
|
+
executables: []
|
|
46
|
+
extensions: []
|
|
47
|
+
extra_rdoc_files: []
|
|
48
|
+
files:
|
|
49
|
+
- Gemfile
|
|
50
|
+
- lib/multi_tabular.rb
|
|
51
|
+
- lib/multi_tabular/references.rb
|
|
52
|
+
- lib/multi_tabular/sub.rb
|
|
53
|
+
- lib/multi_tabular/super.rb
|
|
54
|
+
- lib/multi_tabular/version.rb
|
|
55
|
+
homepage:
|
|
56
|
+
licenses:
|
|
57
|
+
- MIT
|
|
58
|
+
metadata: {}
|
|
59
|
+
post_install_message:
|
|
60
|
+
rdoc_options: []
|
|
61
|
+
require_paths:
|
|
62
|
+
- lib
|
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '2.0'
|
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
69
|
+
requirements:
|
|
70
|
+
- - ">="
|
|
71
|
+
- !ruby/object:Gem::Version
|
|
72
|
+
version: '0'
|
|
73
|
+
requirements: []
|
|
74
|
+
rubyforge_project:
|
|
75
|
+
rubygems_version: 2.4.4
|
|
76
|
+
signing_key:
|
|
77
|
+
specification_version: 4
|
|
78
|
+
summary: True multi table inheritance for ActiveRecord.
|
|
79
|
+
test_files: []
|