sequel 4.13.0 → 4.14.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.
- checksums.yaml +4 -4
- data/CHANGELOG +24 -0
- data/doc/active_record.rdoc +4 -4
- data/doc/advanced_associations.rdoc +2 -2
- data/doc/association_basics.rdoc +11 -11
- data/doc/cheat_sheet.rdoc +7 -7
- data/doc/core_extensions.rdoc +1 -1
- data/doc/dataset_filtering.rdoc +1 -1
- data/doc/extensions.rdoc +1 -1
- data/doc/migration.rdoc +3 -3
- data/doc/model_hooks.rdoc +1 -1
- data/doc/opening_databases.rdoc +4 -0
- data/doc/postgresql.rdoc +2 -2
- data/doc/prepared_statements.rdoc +1 -1
- data/doc/querying.rdoc +31 -31
- data/doc/release_notes/4.13.0.txt +1 -1
- data/doc/release_notes/4.14.0.txt +68 -0
- data/doc/schema_modification.rdoc +1 -1
- data/doc/sharding.rdoc +2 -2
- data/doc/sql.rdoc +1 -1
- data/doc/virtual_rows.rdoc +2 -2
- data/lib/sequel/adapters/jdbc/jtds.rb +4 -0
- data/lib/sequel/adapters/mysql.rb +18 -18
- data/lib/sequel/adapters/mysql2.rb +7 -7
- data/lib/sequel/adapters/shared/mysql.rb +15 -5
- data/lib/sequel/adapters/shared/postgres.rb +71 -58
- data/lib/sequel/adapters/shared/sqlite.rb +2 -2
- data/lib/sequel/ast_transformer.rb +1 -1
- data/lib/sequel/connection_pool/sharded_single.rb +8 -8
- data/lib/sequel/connection_pool/sharded_threaded.rb +8 -8
- data/lib/sequel/database/connecting.rb +1 -1
- data/lib/sequel/database/schema_generator.rb +12 -0
- data/lib/sequel/database/schema_methods.rb +8 -7
- data/lib/sequel/database/transactions.rb +1 -2
- data/lib/sequel/dataset/actions.rb +4 -4
- data/lib/sequel/dataset/graph.rb +4 -0
- data/lib/sequel/dataset/query.rb +18 -18
- data/lib/sequel/dataset/sql.rb +3 -3
- data/lib/sequel/extensions/_pretty_table.rb +1 -0
- data/lib/sequel/extensions/arbitrary_servers.rb +3 -2
- data/lib/sequel/extensions/columns_introspection.rb +1 -0
- data/lib/sequel/extensions/connection_validator.rb +1 -0
- data/lib/sequel/extensions/constraint_validations.rb +1 -0
- data/lib/sequel/extensions/current_datetime_timestamp.rb +1 -0
- data/lib/sequel/extensions/dataset_source_alias.rb +1 -0
- data/lib/sequel/extensions/date_arithmetic.rb +1 -0
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +1 -0
- data/lib/sequel/extensions/error_sql.rb +1 -0
- data/lib/sequel/extensions/eval_inspect.rb +1 -0
- data/lib/sequel/extensions/filter_having.rb +1 -0
- data/lib/sequel/extensions/from_block.rb +1 -0
- data/lib/sequel/extensions/graph_each.rb +1 -0
- data/lib/sequel/extensions/hash_aliases.rb +1 -0
- data/lib/sequel/extensions/looser_typecasting.rb +1 -0
- data/lib/sequel/extensions/meta_def.rb +1 -0
- data/lib/sequel/extensions/migration.rb +1 -0
- data/lib/sequel/extensions/mssql_emulate_lateral_with_apply.rb +1 -0
- data/lib/sequel/extensions/named_timezones.rb +1 -0
- data/lib/sequel/extensions/null_dataset.rb +1 -0
- data/lib/sequel/extensions/pagination.rb +1 -0
- data/lib/sequel/extensions/pg_array.rb +2 -2
- data/lib/sequel/extensions/pg_array_ops.rb +1 -0
- data/lib/sequel/extensions/pg_enum.rb +1 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +1 -0
- data/lib/sequel/extensions/pg_json_ops.rb +1 -0
- data/lib/sequel/extensions/pg_loose_count.rb +1 -0
- data/lib/sequel/extensions/pg_range_ops.rb +1 -0
- data/lib/sequel/extensions/pg_row_ops.rb +1 -0
- data/lib/sequel/extensions/pg_static_cache_updater.rb +1 -0
- data/lib/sequel/extensions/pretty_table.rb +1 -0
- data/lib/sequel/extensions/query.rb +1 -0
- data/lib/sequel/extensions/query_literals.rb +1 -0
- data/lib/sequel/extensions/schema_caching.rb +1 -0
- data/lib/sequel/extensions/schema_dumper.rb +1 -1
- data/lib/sequel/extensions/select_remove.rb +1 -0
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +1 -0
- data/lib/sequel/extensions/server_block.rb +1 -0
- data/lib/sequel/extensions/set_overrides.rb +1 -0
- data/lib/sequel/extensions/split_array_nil.rb +1 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +1 -0
- data/lib/sequel/extensions/to_dot.rb +1 -0
- data/lib/sequel/model/associations.rb +5 -5
- data/lib/sequel/model/base.rb +3 -3
- data/lib/sequel/plugins/association_proxies.rb +1 -1
- data/lib/sequel/plugins/caching.rb +8 -3
- data/lib/sequel/plugins/class_table_inheritance.rb +20 -11
- data/lib/sequel/plugins/composition.rb +18 -18
- data/lib/sequel/plugins/json_serializer.rb +3 -3
- data/lib/sequel/plugins/lazy_attributes.rb +23 -9
- data/lib/sequel/plugins/many_through_many.rb +21 -21
- data/lib/sequel/plugins/nested_attributes.rb +7 -3
- data/lib/sequel/plugins/pg_row.rb +1 -1
- data/lib/sequel/plugins/rcte_tree.rb +13 -13
- data/lib/sequel/plugins/sharding.rb +6 -6
- data/lib/sequel/plugins/timestamps.rb +4 -4
- data/lib/sequel/plugins/touch.rb +7 -7
- data/lib/sequel/plugins/tree.rb +1 -1
- data/lib/sequel/plugins/validation_class_methods.rb +36 -36
- data/lib/sequel/plugins/validation_helpers.rb +3 -4
- data/lib/sequel/plugins/xml_serializer.rb +29 -29
- data/lib/sequel/sql.rb +22 -11
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/postgres_spec.rb +10 -0
- data/spec/core/database_spec.rb +3 -4
- data/spec/core/dataset_spec.rb +16 -1
- data/spec/core/expression_filters_spec.rb +12 -0
- data/spec/core/object_graph_spec.rb +5 -0
- data/spec/core/placeholder_literalizer_spec.rb +8 -0
- data/spec/extensions/caching_spec.rb +18 -0
- data/spec/extensions/class_table_inheritance_spec.rb +34 -0
- data/spec/extensions/many_through_many_spec.rb +4 -0
- data/spec/extensions/nested_attributes_spec.rb +59 -4
- data/spec/extensions/pg_array_associations_spec.rb +5 -0
- data/spec/extensions/single_table_inheritance_spec.rb +23 -1
- data/spec/integration/plugin_test.rb +17 -0
- data/spec/model/eager_loading_spec.rb +8 -0
- metadata +4 -2
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
# conversion_procs usingthe appropriate type OID. For user defined
|
|
53
53
|
# types, you can do this via:
|
|
54
54
|
#
|
|
55
|
-
# DB.conversion_procs[scalar_type_oid] = lambda{|string|
|
|
55
|
+
# DB.conversion_procs[scalar_type_oid] = lambda{|string| }
|
|
56
56
|
#
|
|
57
57
|
# Then you can call
|
|
58
58
|
# Sequel::Postgres::PGArray::DatabaseMethods#register_array_type
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
# Sequel::Postgres::PGArray.register. In this case, you'll have
|
|
67
67
|
# to specify the type oids:
|
|
68
68
|
#
|
|
69
|
-
# Sequel::Postgres::PG_TYPES[1234] = lambda{|string|
|
|
69
|
+
# Sequel::Postgres::PG_TYPES[1234] = lambda{|string| }
|
|
70
70
|
# Sequel::Postgres::PGArray.register('foo', :oid=>4321, :scalar_oid=>1234)
|
|
71
71
|
#
|
|
72
72
|
# Both Sequel::Postgres::PGArray::DatabaseMethods#register_array_type
|
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
# PostgreSQL arrays will have the returned expression automatically wrapped in a
|
|
67
67
|
# Postgres::ArrayOp if the pg_array_ops extension is loaded.
|
|
68
68
|
|
|
69
|
+
#
|
|
69
70
|
module Sequel
|
|
70
71
|
module Postgres
|
|
71
72
|
# The HStoreOp class is a simple container for a single object that
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
# loading this extension. Doing so will allow you to use PGArray#op to get
|
|
53
53
|
# an RangeOp, allowing you to perform range operations on range literals.
|
|
54
54
|
|
|
55
|
+
#
|
|
55
56
|
module Sequel
|
|
56
57
|
module Postgres
|
|
57
58
|
# The RangeOp class is a simple container for a single object that
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
# and it handles all ruby objects used in the schema hash. Because of this,
|
|
43
43
|
# you should not attempt to load the schema from a untrusted file.
|
|
44
44
|
|
|
45
|
+
#
|
|
45
46
|
module Sequel
|
|
46
47
|
module SchemaCaching
|
|
47
48
|
# Dump the cached schema to the filename given in Marshal format.
|
|
@@ -105,7 +105,7 @@ END_MIG
|
|
|
105
105
|
# will yield the same type. Without this set, types that aren't
|
|
106
106
|
# recognized will be translated to a string-like type.
|
|
107
107
|
# :foreign_keys :: If set to false, don't dump foreign_keys (they can be
|
|
108
|
-
#
|
|
108
|
+
# added later via #dump_foreign_key_migration)
|
|
109
109
|
# :indexes :: If set to false, don't dump indexes (they can be added
|
|
110
110
|
# later via #dump_index_migration).
|
|
111
111
|
# :index_names :: If set to false, don't record names of indexes. If
|
|
@@ -1791,10 +1791,10 @@ module Sequel
|
|
|
1791
1791
|
select_all(egds.first_source).
|
|
1792
1792
|
select_append(*associated_key_array)
|
|
1793
1793
|
egds = opts.apply_eager_graph_limit_strategy(egls, egds)
|
|
1794
|
-
ds.graph(egds, associated_key_array.map{|v| v.alias}.zip(lpkcs) + conditions, :qualify=>:deep, :table_alias=>eo[:table_alias], :implicit_qualifier=>eo[:implicit_qualifier], :join_type=>eo[:join_type]||join_type, :from_self_alias=>eo[:from_self_alias], :select=>select||orig_egds.columns, &graph_block)
|
|
1794
|
+
ds.graph(egds, associated_key_array.map{|v| v.alias}.zip(lpkcs) + conditions, :qualify=>:deep, :table_alias=>eo[:table_alias], :implicit_qualifier=>eo[:implicit_qualifier], :join_type=>eo[:join_type]||join_type, :from_self_alias=>eo[:from_self_alias], :join_only=>eo[:join_only], :select=>select||orig_egds.columns, &graph_block)
|
|
1795
1795
|
else
|
|
1796
|
-
ds = ds.graph(join_table, use_jt_only_conditions ? jt_only_conditions : lcks.zip(lpkcs) + graph_jt_conds, :select=>false, :table_alias=>ds.unused_table_alias(join_table, [eo[:table_alias]]), :join_type=>eo[:join_type]||jt_join_type, :implicit_qualifier=>eo[:implicit_qualifier], :qualify=>:deep, :from_self_alias=>eo[:from_self_alias], &jt_graph_block)
|
|
1797
|
-
ds.graph(eager_graph_dataset(opts, eo), use_only_conditions ? only_conditions : opts.right_primary_keys.zip(rcks) + conditions, :select=>select, :table_alias=>eo[:table_alias], :qualify=>:deep, :join_type=>eo[:join_type]||join_type, &graph_block)
|
|
1796
|
+
ds = ds.graph(join_table, use_jt_only_conditions ? jt_only_conditions : lcks.zip(lpkcs) + graph_jt_conds, :select=>false, :table_alias=>ds.unused_table_alias(join_table, [eo[:table_alias]]), :join_type=>eo[:join_type]||jt_join_type, :join_only=>eo[:join_only], :implicit_qualifier=>eo[:implicit_qualifier], :qualify=>:deep, :from_self_alias=>eo[:from_self_alias], &jt_graph_block)
|
|
1797
|
+
ds.graph(eager_graph_dataset(opts, eo), use_only_conditions ? only_conditions : opts.right_primary_keys.zip(rcks) + conditions, :select=>select, :table_alias=>eo[:table_alias], :qualify=>:deep, :join_type=>eo[:join_type]||join_type, :join_only=>eo[:join_only], &graph_block)
|
|
1798
1798
|
end
|
|
1799
1799
|
end
|
|
1800
1800
|
|
|
@@ -2561,7 +2561,7 @@ END
|
|
|
2561
2561
|
end
|
|
2562
2562
|
local_opts = ds.opts[:eager_graph][:local]
|
|
2563
2563
|
limit_strategy = r.eager_graph_limit_strategy(local_opts[:limit_strategy])
|
|
2564
|
-
ds = loader.call(:self=>ds, :table_alias=>assoc_table_alias, :implicit_qualifier=>(ta == ds.opts[:eager_graph][:master]) ? first_source : qualifier_from_alias_symbol(ta, first_source), :callback=>callback, :join_type=>local_opts[:join_type], :limit_strategy=>limit_strategy, :from_self_alias=>ds.opts[:eager_graph][:master])
|
|
2564
|
+
ds = loader.call(:self=>ds, :table_alias=>assoc_table_alias, :implicit_qualifier=>(ta == ds.opts[:eager_graph][:master]) ? first_source : qualifier_from_alias_symbol(ta, first_source), :callback=>callback, :join_type=>local_opts[:join_type], :join_only=>local_opts[:join_only], :limit_strategy=>limit_strategy, :from_self_alias=>ds.opts[:eager_graph][:master])
|
|
2565
2565
|
if r[:order_eager_graph] && (order = r.fetch(:graph_order, r[:order]))
|
|
2566
2566
|
ds = ds.order_more(*qualified_expression(order, assoc_table_alias))
|
|
2567
2567
|
end
|
|
@@ -2614,7 +2614,7 @@ END
|
|
|
2614
2614
|
# Return a new dataset with JOINs of the given type added, using the tables and
|
|
2615
2615
|
# conditions specified by the associations.
|
|
2616
2616
|
def _association_join(type, associations)
|
|
2617
|
-
clone(:join=>clone(:graph_from_self=>false).eager_graph_with_options(associations, :join_type=>type).opts[:join])
|
|
2617
|
+
clone(:join=>clone(:graph_from_self=>false).eager_graph_with_options(associations, :join_type=>type, :join_only=>true).opts[:join])
|
|
2618
2618
|
end
|
|
2619
2619
|
|
|
2620
2620
|
# If the association has conditions itself, then it requires additional filters be
|
data/lib/sequel/model/base.rb
CHANGED
|
@@ -1351,7 +1351,7 @@ module Sequel
|
|
|
1351
1351
|
# a = Artist[1]
|
|
1352
1352
|
# Artist.db.transaction do
|
|
1353
1353
|
# a.lock!
|
|
1354
|
-
# a.update(
|
|
1354
|
+
# a.update(:name=>'A')
|
|
1355
1355
|
# end
|
|
1356
1356
|
def lock!
|
|
1357
1357
|
_refresh(this.for_update) unless new?
|
|
@@ -2091,7 +2091,7 @@ module Sequel
|
|
|
2091
2091
|
# Returns all methods that can be used for attribute assignment (those that end with =),
|
|
2092
2092
|
# depending on the type:
|
|
2093
2093
|
#
|
|
2094
|
-
# :default :: Use the default methods allowed in
|
|
2094
|
+
# :default :: Use the default methods allowed in the model class.
|
|
2095
2095
|
# :all :: Allow setting all setters, except those specifically restricted (such as ==).
|
|
2096
2096
|
# Array :: Only allow setting of columns in the given array.
|
|
2097
2097
|
def setter_methods(type)
|
|
@@ -2249,7 +2249,7 @@ module Sequel
|
|
|
2249
2249
|
# If there is no order already defined on this dataset, order it by
|
|
2250
2250
|
# the primary key and call paged_each.
|
|
2251
2251
|
#
|
|
2252
|
-
# Album.paged_each{|row|
|
|
2252
|
+
# Album.paged_each{|row| }
|
|
2253
2253
|
# # SELECT * FROM albums ORDER BY id LIMIT 1000 OFFSET 0
|
|
2254
2254
|
# # SELECT * FROM albums ORDER BY id LIMIT 1000 OFFSET 1000
|
|
2255
2255
|
# # SELECT * FROM albums ORDER BY id LIMIT 1000 OFFSET 2000
|
|
@@ -35,7 +35,7 @@ module Sequel
|
|
|
35
35
|
# :arguments => [2],
|
|
36
36
|
# :block => {|x| 3},
|
|
37
37
|
# :instance => artist,
|
|
38
|
-
# :reflection => {:name=>:albums
|
|
38
|
+
# :reflection => {:name=>:albums} # AssociationReflection instance
|
|
39
39
|
# :proxy_argument => 1,
|
|
40
40
|
# :proxy_block => {|ds| ds}
|
|
41
41
|
# }
|
|
@@ -7,8 +7,8 @@ module Sequel
|
|
|
7
7
|
# cache_store.set(key, obj, time) # Associate the obj with the given key
|
|
8
8
|
# # in the cache for the time (specified
|
|
9
9
|
# # in seconds).
|
|
10
|
-
# cache_store.get(key) => obj
|
|
11
|
-
# cache_store.get(key2) => nil
|
|
10
|
+
# cache_store.get(key) # => obj # Returns object set with same key.
|
|
11
|
+
# cache_store.get(key2) # => nil # nil returned if there isn't an object
|
|
12
12
|
# # currently in the cache with that key.
|
|
13
13
|
# cache_store.delete(key) # Remove key from cache
|
|
14
14
|
#
|
|
@@ -64,10 +64,15 @@ module Sequel
|
|
|
64
64
|
cache_get(cache_key(pk))
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
+
# Returns the prefix used to namespace this class in the cache.
|
|
68
|
+
def cache_key_prefix
|
|
69
|
+
"#{self}"
|
|
70
|
+
end
|
|
71
|
+
|
|
67
72
|
# Return a key string for the given primary key.
|
|
68
73
|
def cache_key(pk)
|
|
69
74
|
raise(Error, 'no primary key for this record') unless pk.is_a?(Array) ? pk.all? : pk
|
|
70
|
-
"#{
|
|
75
|
+
"#{cache_key_prefix}:#{Array(pk).join(',')}"
|
|
71
76
|
end
|
|
72
77
|
|
|
73
78
|
Plugins.inherited_instance_variables(self, :@cache_store=>nil, :@cache_ttl=>nil, :@cache_ignore_exceptions=>nil)
|
|
@@ -13,20 +13,20 @@ module Sequel
|
|
|
13
13
|
#
|
|
14
14
|
# the following database schema may be used (table - columns):
|
|
15
15
|
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
16
|
+
# employees :: id, name, kind
|
|
17
|
+
# staff :: id, manager_id
|
|
18
|
+
# managers :: id, num_staff
|
|
19
|
+
# executives :: id, num_managers
|
|
20
20
|
#
|
|
21
21
|
# The class_table_inheritance plugin assumes that the main table
|
|
22
22
|
# (e.g. employees) has a primary key field (usually autoincrementing),
|
|
23
23
|
# and all other tables have a foreign key of the same name that points
|
|
24
24
|
# to the same key in their superclass's table. For example:
|
|
25
25
|
#
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
#
|
|
26
|
+
# employees.id :: primary key, autoincrementing
|
|
27
|
+
# staff.id :: foreign key referencing employees(id)
|
|
28
|
+
# managers.id :: foreign key referencing employees(id)
|
|
29
|
+
# executives.id :: foreign key referencing managers(id)
|
|
30
30
|
#
|
|
31
31
|
# When using the class_table_inheritance plugin, subclasses use joined
|
|
32
32
|
# datasets:
|
|
@@ -62,6 +62,13 @@ module Sequel
|
|
|
62
62
|
# a = Employee.all # [<#Staff>, <#Manager>, <#Executive>]
|
|
63
63
|
# a.first.values # {:id=>1, name=>'S', :kind=>'Staff'}
|
|
64
64
|
# a.first.manager_id # Loads the manager_id attribute from the database
|
|
65
|
+
#
|
|
66
|
+
# If you want to get all columns in a subclass instance after loading
|
|
67
|
+
# via the superclass, call Model#refresh.
|
|
68
|
+
#
|
|
69
|
+
# a = Employee.first
|
|
70
|
+
# a.values # {:id=>1, name=>'S', :kind=>'Executive'}
|
|
71
|
+
# a.refresh.values # {:id=>1, name=>'S', :kind=>'Executive', :num_staff=>4, :num_managers=>2}
|
|
65
72
|
#
|
|
66
73
|
# Usage:
|
|
67
74
|
#
|
|
@@ -159,6 +166,8 @@ module Sequel
|
|
|
159
166
|
cmm = cti_model_map
|
|
160
167
|
pk = primary_key
|
|
161
168
|
ds = dataset
|
|
169
|
+
table = nil
|
|
170
|
+
columns = nil
|
|
162
171
|
subclass.instance_eval do
|
|
163
172
|
raise(Error, "cannot create anonymous subclass for model class using class_table_inheritance") if !(n = name) || n.empty?
|
|
164
173
|
table = ctm[n.to_sym] || implicit_table_name
|
|
@@ -178,9 +187,9 @@ module Sequel
|
|
|
178
187
|
super
|
|
179
188
|
subclass.instance_eval do
|
|
180
189
|
set_dataset_cti_row_proc
|
|
181
|
-
(columns - [cbm.primary_key]).each{|a| define_lazy_attribute_getter(a)}
|
|
182
|
-
cti_tables.reverse.each do |
|
|
183
|
-
db.schema(
|
|
190
|
+
(columns - [cbm.primary_key]).each{|a| define_lazy_attribute_getter(a, :dataset=>dataset, :table=>table)}
|
|
191
|
+
cti_tables.reverse.each do |t|
|
|
192
|
+
db.schema(t).each{|k,v| db_schema[k] = v}
|
|
184
193
|
end
|
|
185
194
|
end
|
|
186
195
|
end
|
|
@@ -72,24 +72,24 @@ module Sequel
|
|
|
72
72
|
# You must provide either a :mapping option or both the :composer and :decomposer options.
|
|
73
73
|
#
|
|
74
74
|
# Options:
|
|
75
|
-
#
|
|
76
|
-
#
|
|
77
|
-
#
|
|
78
|
-
#
|
|
79
|
-
#
|
|
80
|
-
#
|
|
81
|
-
#
|
|
82
|
-
#
|
|
83
|
-
#
|
|
84
|
-
#
|
|
85
|
-
#
|
|
86
|
-
#
|
|
87
|
-
#
|
|
88
|
-
#
|
|
89
|
-
#
|
|
90
|
-
#
|
|
91
|
-
#
|
|
92
|
-
#
|
|
75
|
+
# :class :: if using the :mapping option, the class to use, as a Class, String or Symbol.
|
|
76
|
+
# :composer :: A proc that is instance evaled when the composition getter method is called
|
|
77
|
+
# to create the composition.
|
|
78
|
+
# :decomposer :: A proc that is instance evaled before saving the model object,
|
|
79
|
+
# if the composition object exists, which sets the columns in the model object
|
|
80
|
+
# based on the value of the composition object.
|
|
81
|
+
# :mapping :: An array where each element is either a symbol or an array of two symbols.
|
|
82
|
+
# A symbol is treated like an array of two symbols where both symbols are the same.
|
|
83
|
+
# The first symbol represents the getter method in the model, and the second symbol
|
|
84
|
+
# represents the getter method in the composition object. Example:
|
|
85
|
+
# # Uses columns year, month, and day in the current model
|
|
86
|
+
# # Uses year, month, and day methods in the composition object
|
|
87
|
+
# {:mapping=>[:year, :month, :day]}
|
|
88
|
+
# # Uses columns year, month, and day in the current model
|
|
89
|
+
# # Uses y, m, and d methods in the composition object where
|
|
90
|
+
# # for example y in the composition object represents year
|
|
91
|
+
# # in the model object.
|
|
92
|
+
# {:mapping=>[[:year, :y], [:month, :m], [:day, :d]]}
|
|
93
93
|
def composition(name, opts=OPTS)
|
|
94
94
|
opts = opts.dup
|
|
95
95
|
compositions[name] = opts
|