sequel-table_inheritance 0.1.0 → 0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a970fd131bbbece81669fee96f7ce23277c59b65
4
- data.tar.gz: 8c0db19ecf4ec040f34a00e71053e8b1c76fc5b3
3
+ metadata.gz: b67c3763d27dc1f170724e94da63e7e2ba40c3ab
4
+ data.tar.gz: be5bec3b9d2c7a035d115d0f6fa7eecff47b0888
5
5
  SHA512:
6
- metadata.gz: c3b70ea2393962841410421938bef62f8dabdb5da6af50728334b0c8dbf5ca2e060827cadeef5057e9f40e7b1aee26528dc508c5f3f78c152d39efd7cbab69dc
7
- data.tar.gz: 85e639a0ccb4f8f5c0e82c955aa9f860e9576e80ac13d4668f1777a53e5b0568cfdd9ea03f312a3460b008b67767ba286d570713a8c5088acb4075d0f1f6ad8c
6
+ metadata.gz: ec03d9e27d385a094c8967574bd70eb6c63861ea6a830d49715ec3f2feda6f4bbf2c40b5aaf5f7526afcecb7f41f7e09c01c3c00df62291a9bb5b5265f67a4fe
7
+ data.tar.gz: d84fd765d8c69354de64d0a7f06bae564c59b041559ee5a701a35cdb9aa3ebd9c47d2da0c947e598e85b734769361ee11dfa336dcf0e276b943732ffca326e01
data/README.rdoc CHANGED
@@ -2,198 +2,28 @@
2
2
 
3
3
  This is a sequel plugin that combines the functionality of the single and class
4
4
  table inheritance plugins. This plugin uses the single_table_inheritance plugin
5
- and should work as a drop in replacement for the class_table_inheritance plugins.
5
+ and should work as a drop in replacement for the class_table_inheritance plugin.
6
6
  This allows using new tables for subclasses only when need for additional columns
7
7
  or possibly referential integrity to exclusively subclassed rows.
8
8
 
9
9
  == Additional features over the class table inheritance plugin
10
10
  For class table inheritance use this provides additional functionality beyond
11
- the standard class table inheritance plugin including the following:
11
+ the standard class_table_inheritance plugin including the following:
12
12
 
13
- * Eager loading in addition to lazy loading of subclasses
13
+ * Eager loading in addition to lazy loading of subclasses.
14
14
  * Use RETURNING * on insert if available avoiding a select query after new model saves
15
- * Features found in the single table inheritance not in class table inheritance
15
+ * Features found in the single_table_inheritance not in class_table_inheritance
16
16
  Notably the key_map, key_chooser options and accepting a proc in addition to
17
17
  a hash for model_map option
18
18
 
19
- == Documentation
20
- === Overview
19
+ == Using sequel-table_inheritance
21
20
 
22
- The hybrid_table_inheritance pluging allows model subclasses to be stored
23
- in either the same table as the parent model or a different table with a key
24
- referencing the parent table.
25
- This combines the functionality of single and class (multiple) table inheritance
26
- into one plugin. This plugin uses the single_table_inheritance plugin
27
- and should work as a drop in replacement for the class_table_inheritance plugins.
28
- This allows introducing new tables only when needed typically for additional
29
- fields or possibly referential integrity to subclassed objects.
21
+ Include the sequel-hybrid_table gem in your Gemfile
22
+ gem "sequel-table_inheritance"
30
23
 
31
- === Detail
24
+ run "bundle install" if needed
32
25
 
33
- For example, with this hierarchy:
26
+ The hybrid_table_inheritance plugin should now work like any other sequel plugin.
27
+ You should be able to use in place of the class_table_inheritance plugin.
34
28
 
35
- Employee
36
- / \
37
- Staff Manager
38
- | |
39
- Cook Executive
40
- |
41
- CEO
42
-
43
- the following database schema may be used (table - columns):
44
-
45
- employees :: id, name, kind
46
- staff :: id, manager_id
47
- managers :: id, num_staff
48
- executives :: id, num_managers
49
-
50
- The hybrid_table_inheritance plugin assumes that the root table
51
- (e.g. employees) has a primary key field (usually autoincrementing),
52
- and all other tables have a foreign key of the same name that points
53
- to the same key in their superclass's table. In this example,
54
- the employees id column is a primary key and the id column in every
55
- other table is a foreign key referencing the employees id.
56
-
57
- In this example the employees table stores Staff model objects and the
58
- executives table stores CEO model objects.
59
-
60
- When using the class_table_inheritance plugin, subclasses use joined
61
- datasets:
62
-
63
- Employee.dataset.sql
64
- # SELECT * FROM employees
65
-
66
- Manager.dataset.sql
67
- # SELECT employees.id, employees.name, employees.kind,
68
- # managers.num_staff
69
- # FROM employees
70
- # JOIN managers ON (managers.id = employees.id)
71
-
72
- CEO.dataset.sql
73
- # SELECT employees.id, employees.name, employees.kind,
74
- # managers.num_staff, executives.num_managers
75
- # FROM employees
76
- # JOIN managers ON (managers.id = employees.id)
77
- # JOIN executives ON (executives.id = managers.id)
78
- # WHERE (employees.kind IN ('CEO'))
79
-
80
- This allows CEO.all to return instances with all attributes
81
- loaded. The plugin overrides the deleting, inserting, and updating
82
- in the model to work with multiple tables, by handling each table
83
- individually.
84
-
85
- === Subclass loading
86
-
87
- When model objects are retrieved for a superclass the result could be
88
- subclass objects needing additional attributes from other tables.
89
- This plugin can load those additional attributes immediately with eager
90
- loading or when requested on the object with lazy loading.
91
-
92
- With eager loading, the additional needed rows will be loaded with the
93
- all or first methods. Note that eager loading does not work
94
- with the each method because all of the records must be loaded to
95
- determine the keys for each subclass query. In that case lazy loading can
96
- be used or the each method used on the result of the all method.
97
-
98
- If lazy loading is used the lazy_attributes plugin will be included to
99
- return subclass specific attributes that were not loaded
100
- when calling superclass methods (since those wouldn't join
101
- to the subclass tables). For example:
102
-
103
- a = Employee.all # [<#Staff>, <#Manager>, <#Executive>]
104
- a.first.values # {:id=>1, name=>'S', :kind=>'Staff'}
105
- a.first.manager_id # Loads the manager_id attribute from the database
106
-
107
- If you want to get all columns in a subclass instance after loading
108
- via the superclass, call Model#refresh.
109
-
110
- a = Employee.first
111
- a.values # {:id=>1, name=>'S', :kind=>'CEO'}
112
- a.refresh.values # {:id=>1, name=>'S', :kind=>'Executive', :num_staff=>4, :num_managers=>2}
113
-
114
- The option :subclass_load sets the default subclass loading strategy.
115
- It accepts :eager, :eager_only, :lazy or :lazy_only with a default of :lazy
116
- The _only options will only allow that strategy to be used.
117
- In addition eager or lazy can be called on a dataset to override the default
118
- strategy used assuming an _only option was not set.
119
-
120
- === Usage
121
-
122
- # Use the default of storing the class name in the sti_key
123
- # column (:kind in this case)
124
- class Employee < Sequel::Model
125
- plugin :hybrid_table_inheritance, :key=>:kind
126
- end
127
-
128
- # Have subclasses inherit from the appropriate class
129
- class Staff < Employee; end # uses staff table
130
- class Cook < Staff; end # cooks table doesn't exist so uses staff table
131
- class Manager < Employee; end # uses managers table
132
- class Executive < Manager; end # uses executives table
133
- class CEO < Executive; end # ceos table doesn't exist so uses executives table
134
-
135
- # Some examples of using these options:
136
-
137
- # Specifying the tables with a :table_map hash
138
- Employee.plugin :hybrid_table_inheritance,
139
- :table_map=>{:Employee => :employees,
140
- :Staff => :staff,
141
- :Cook => :staff,
142
- :Manager => :managers,
143
- :Executive => :executives,
144
- :CEO => :executives }
145
-
146
- # Using integers to store the class type, with a :model_map hash
147
- # and an sti_key of :type
148
- Employee.plugin :hybrid_table_inheritance, :type,
149
- :model_map=>{1=>:Staff, 2=>:Cook, 3=>:Manager, 4=>:Executive, 5=>:CEO}
150
-
151
- # Using non-class name strings
152
- Employee.plugin :hybrid_table_inheritance, :key=>:type,
153
- :model_map=>{'staff'=>:Staff, 'cook staff'=>:Cook, 'supervisor'=>:Manager}
154
-
155
- # By default the plugin sets the respective column value
156
- # when a new instance is created.
157
- Cook.create.type == 'cook staff'
158
- Manager.create.type == 'supervisor'
159
-
160
- # You can customize this behavior with the :key_chooser option.
161
- # This is most useful when using a non-bijective mapping.
162
- Employee.plugin :hybrid_table_inheritance, :key=>:type,
163
- :model_map=>{'cook staff'=>:Cook, 'supervisor'=>:Manager},
164
- :key_chooser=>proc{|instance| instance.model.sti_key_map[instance.model.to_s].first || 'stranger' }
165
-
166
- # Using custom procs, with :model_map taking column values
167
- # and yielding either a class, string, symbol, or nil,
168
- # and :key_map taking a class object and returning the column
169
- # value to use
170
- Employee.plugin :single_table_inheritance, :key=>:type,
171
- :model_map=>proc{|v| v.reverse},
172
- :key_map=>proc{|klass| klass.name.reverse}
173
-
174
- # You can use the same class for multiple values.
175
- # This is mainly useful when the sti_key column contains multiple values
176
- # which are different but do not require different code.
177
- Employee.plugin :single_table_inheritance, :key=>:type,
178
- :model_map=>{'staff' => "Staff",
179
- 'manager' => "Manager",
180
- 'overpayed staff' => "Staff",
181
- 'underpayed staff' => "Staff"}
182
-
183
- One minor issue to note is that if you specify the <tt>:key_map</tt>
184
- option as a hash, instead of having it inferred from the <tt>:model_map</tt>,
185
- you should only use class name strings as keys, you should not use symbols
186
- as keys.
187
-
188
- == Options
189
- :key :: column symbol that holds the key that identifies the class to use.
190
- Necessary if you want to call model methods on a superclass
191
- that return subclass instances
192
- :model_map :: Hash or proc mapping the key column values to model class names.
193
- :key_map :: Hash or proc mapping model class names to key column values.
194
- Each value or return is an array of possible key column values.
195
- :key_chooser :: proc returning key for the provided model instance
196
- :table_map :: Hash with class name symbols keys mapping to table name symbol values
197
- Overrides implicit table names
198
- :subclass_load :: subclass loading strategy, defaults to :lazy
199
- options: :eager, :eager_only, :lazy or :lazy_only
29
+ Full documentation available at http://www.rubydoc.info/gems/sequel-table_inheritance/Sequel/Plugins/HybridTableInheritance
@@ -9,7 +9,7 @@ module Sequel
9
9
  # into one plugin. This plugin uses the single_table_inheritance plugin
10
10
  # and should work as a drop in replacement for the class_table_inheritance plugins.
11
11
  # This allows introducing new tables only when needed typically for additional
12
- # fields or possibly referential integrity to subclassed objects.
12
+ # fields or possibly referential integrity to subclassed rows.
13
13
  #
14
14
  # = Detail
15
15
  #
@@ -18,7 +18,7 @@ module Sequel
18
18
  # Employee
19
19
  # / \
20
20
  # Staff Manager
21
- # | |
21
+ # | |
22
22
  # Cook Executive
23
23
  # |
24
24
  # CEO
@@ -31,16 +31,16 @@ module Sequel
31
31
  # executives :: id, num_managers
32
32
  #
33
33
  # The hybrid_table_inheritance plugin assumes that the root table
34
- # (e.g. employees) has a primary key field (usually autoincrementing),
34
+ # (e.g. employees) has a primary key column (usually autoincrementing),
35
35
  # and all other tables have a foreign key of the same name that points
36
- # to the same key in their superclass's table. In this example,
36
+ # to the same column in their superclass's table. In this example,
37
37
  # the employees id column is a primary key and the id column in every
38
38
  # other table is a foreign key referencing the employees id.
39
39
  #
40
- # In this example the employees table stores Staff model objects and the
40
+ # In this example the staff table stores Cook model objects and the
41
41
  # executives table stores CEO model objects.
42
42
  #
43
- # When using the class_table_inheritance plugin, subclasses use joined
43
+ # When using the class_table_inheritance plugin, subclasses can use joined
44
44
  # datasets:
45
45
  #
46
46
  # Employee.dataset.sql
@@ -68,18 +68,18 @@ module Sequel
68
68
  # = Subclass loading
69
69
  #
70
70
  # When model objects are retrieved for a superclass the result could be
71
- # subclass objects needing additional attributes from other tables.
72
- # This plugin can load those additional attributes immediately with eager
73
- # loading or when requested on the object with lazy loading.
71
+ # subclass objects needing additional values from other tables.
72
+ # This plugin can load those additional values immediately with eager
73
+ # loading or when requested on the model object with lazy loading.
74
74
  #
75
75
  # With eager loading, the additional needed rows will be loaded with the
76
76
  # all or first methods. Note that eager loading does not work
77
- # with the each method because all of the records must be loaded to
78
- # determine the keys for each subclass query. In that case lazy loading can
77
+ # with the each method because all of the model objects must be loaded to
78
+ # determine the keys for each subclass table query. In that case lazy loading can
79
79
  # be used or the each method used on the result of the all method.
80
80
  #
81
- # If lazy loading is used the lazy_attributes plugin will be included to
82
- # return subclass specific attributes that were not loaded
81
+ # Unless lazy loading is disabled, the lazy_attributes plugin will be
82
+ # included to return subclass specific values that were not loaded
83
83
  # when calling superclass methods (since those wouldn't join
84
84
  # to the subclass tables). For example:
85
85
  #
@@ -168,26 +168,26 @@ module Sequel
168
168
  # you should only use class name strings as keys, you should not use symbols
169
169
  # as keys.
170
170
  module HybridTableInheritance
171
- # The class_table_inheritance plugin requires the lazy_attributes plugin
172
- # to handle lazily-loaded attributes for subclass instances returned
173
- # by superclass methods.
171
+ # The hybrid_table_inheritance plugin requires the single_table_inheritance
172
+ # plugin and the lazy_attributes plugin to handle lazily-loaded attributes
173
+ # for subclass instances returned by superclass methods.
174
174
  def self.apply(model, opts = OPTS)
175
175
  model.plugin :single_table_inheritance, nil
176
176
  model.plugin :lazy_attributes unless opts[:subclass_load] == :eager_only
177
177
  end
178
178
 
179
- # Setup the plugin using the following options:
180
- # :key :: column symbol that holds the key that identifies the class to use.
181
- # Necessary if you want to call model methods on a superclass
182
- # that return subclass instances
183
- # :model_map :: Hash or proc mapping the key column values to model class names.
184
- # :key_map :: Hash or proc mapping model class names to key column values.
185
- # Each value or return is an array of possible key column values.
186
- # :key_chooser :: proc returning key for the provided model instance
187
- # :table_map :: Hash with class name symbols keys mapping to table name symbol values
188
- # Overrides implicit table names
189
- # :subclass_load :: subclass loading strategy, defaults to :lazy
190
- # options: :eager, :eager_only, :lazy or :lazy_only
179
+ # Initialize the plugin using the following options:
180
+ # :key :: Column symbol that holds the key that identifies the class to use.
181
+ # Necessary if you want to call model methods on a superclass
182
+ # that return subclass instances
183
+ # :model_map :: Hash or proc mapping the key column values to model class names.
184
+ # :key_map :: Hash or proc mapping model class names to key column values.
185
+ # Each value or return is an array of possible key column values.
186
+ # :key_chooser :: proc returning key for the provided model instance
187
+ # :table_map :: Hash with class name symbols keys mapping to table name symbol values
188
+ # Overrides implicit table names
189
+ # :subclass_load :: subclass loading strategy, defaults to :lazy
190
+ # options: :eager, :eager_only, :lazy or :lazy_only
191
191
  def self.configure(model, opts = OPTS)
192
192
  SingleTableInheritance.configure model, opts[:key], opts
193
193
 
@@ -5,7 +5,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "sequel-table_inheritance"
8
- s.version = '0.1.0' #Sequel::TableInheritance::VERSION
8
+ s.version = '0.1.2'
9
9
  s.authors = ["Quinn Harris"]
10
10
  s.email = ["sequel@quinnharris.me"]
11
11
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel-table_inheritance
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Quinn Harris
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-23 00:00:00.000000000 Z
11
+ date: 2015-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler