sequel 3.21.0 → 3.41.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.
- data/CHANGELOG +1131 -3
- data/MIT-LICENSE +1 -1
- data/README.rdoc +106 -65
- data/Rakefile +59 -27
- data/bin/sequel +50 -26
- data/doc/active_record.rdoc +68 -52
- data/doc/advanced_associations.rdoc +201 -75
- data/doc/association_basics.rdoc +327 -79
- data/doc/bin_sequel.rdoc +144 -0
- data/doc/cheat_sheet.rdoc +21 -21
- data/doc/core_extensions.rdoc +374 -0
- data/doc/dataset_basics.rdoc +10 -10
- data/doc/dataset_filtering.rdoc +54 -42
- data/doc/mass_assignment.rdoc +56 -0
- data/doc/migration.rdoc +89 -557
- data/doc/model_hooks.rdoc +80 -29
- data/doc/object_model.rdoc +576 -0
- data/doc/opening_databases.rdoc +121 -53
- data/doc/prepared_statements.rdoc +41 -15
- data/doc/querying.rdoc +137 -56
- data/doc/reflection.rdoc +36 -10
- data/doc/release_notes/3.22.0.txt +39 -0
- data/doc/release_notes/3.23.0.txt +172 -0
- data/doc/release_notes/3.24.0.txt +420 -0
- data/doc/release_notes/3.25.0.txt +88 -0
- data/doc/release_notes/3.26.0.txt +88 -0
- data/doc/release_notes/3.27.0.txt +82 -0
- data/doc/release_notes/3.28.0.txt +304 -0
- data/doc/release_notes/3.29.0.txt +459 -0
- data/doc/release_notes/3.30.0.txt +135 -0
- data/doc/release_notes/3.31.0.txt +146 -0
- data/doc/release_notes/3.32.0.txt +202 -0
- data/doc/release_notes/3.33.0.txt +157 -0
- data/doc/release_notes/3.34.0.txt +671 -0
- data/doc/release_notes/3.35.0.txt +144 -0
- data/doc/release_notes/3.36.0.txt +245 -0
- data/doc/release_notes/3.37.0.txt +338 -0
- data/doc/release_notes/3.38.0.txt +234 -0
- data/doc/release_notes/3.39.0.txt +237 -0
- data/doc/release_notes/3.40.0.txt +73 -0
- data/doc/release_notes/3.41.0.txt +155 -0
- data/doc/schema_modification.rdoc +585 -0
- data/doc/sharding.rdoc +99 -8
- data/doc/sql.rdoc +154 -112
- data/doc/testing.rdoc +169 -0
- data/doc/thread_safety.rdoc +17 -0
- data/doc/transactions.rdoc +137 -0
- data/doc/validations.rdoc +1 -1
- data/doc/virtual_rows.rdoc +78 -43
- data/lib/sequel/adapters/ado/access.rb +334 -0
- data/lib/sequel/adapters/ado/mssql.rb +18 -12
- data/lib/sequel/adapters/ado.rb +69 -21
- data/lib/sequel/adapters/amalgalite.rb +17 -14
- data/lib/sequel/adapters/cubrid.rb +143 -0
- data/lib/sequel/adapters/db2.rb +178 -85
- data/lib/sequel/adapters/dbi.rb +19 -21
- data/lib/sequel/adapters/do/mysql.rb +17 -11
- data/lib/sequel/adapters/do/postgres.rb +2 -61
- data/lib/sequel/adapters/do/sqlite.rb +0 -10
- data/lib/sequel/adapters/do.rb +20 -39
- data/lib/sequel/adapters/firebird.rb +33 -210
- data/lib/sequel/adapters/ibmdb.rb +452 -0
- data/lib/sequel/adapters/informix.rb +6 -29
- data/lib/sequel/adapters/jdbc/as400.rb +16 -34
- data/lib/sequel/adapters/jdbc/cubrid.rb +52 -0
- data/lib/sequel/adapters/jdbc/db2.rb +78 -0
- data/lib/sequel/adapters/jdbc/derby.rb +325 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
- data/lib/sequel/adapters/jdbc/h2.rb +68 -31
- data/lib/sequel/adapters/jdbc/hsqldb.rb +189 -0
- data/lib/sequel/adapters/jdbc/informix.rb +21 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +40 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
- data/lib/sequel/adapters/jdbc/mysql.rb +16 -28
- data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
- data/lib/sequel/adapters/jdbc/postgresql.rb +77 -52
- data/lib/sequel/adapters/jdbc/progress.rb +21 -0
- data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
- data/lib/sequel/adapters/jdbc/sqlserver.rb +72 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +308 -114
- data/lib/sequel/adapters/mock.rb +372 -0
- data/lib/sequel/adapters/mysql.rb +130 -230
- data/lib/sequel/adapters/mysql2.rb +64 -63
- data/lib/sequel/adapters/odbc/mssql.rb +17 -9
- data/lib/sequel/adapters/odbc.rb +29 -10
- data/lib/sequel/adapters/openbase.rb +7 -11
- data/lib/sequel/adapters/oracle.rb +364 -57
- data/lib/sequel/adapters/postgres.rb +379 -145
- data/lib/sequel/adapters/shared/access.rb +236 -11
- data/lib/sequel/adapters/shared/cubrid.rb +216 -0
- data/lib/sequel/adapters/shared/db2.rb +353 -0
- data/lib/sequel/adapters/shared/firebird.rb +231 -0
- data/lib/sequel/adapters/shared/informix.rb +53 -0
- data/lib/sequel/adapters/shared/mssql.rb +412 -116
- data/lib/sequel/adapters/shared/mysql.rb +396 -89
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +166 -0
- data/lib/sequel/adapters/shared/oracle.rb +262 -45
- data/lib/sequel/adapters/shared/postgres.rb +688 -279
- data/lib/sequel/adapters/shared/progress.rb +5 -8
- data/lib/sequel/adapters/shared/sqlite.rb +317 -96
- data/lib/sequel/adapters/sqlite.rb +109 -46
- data/lib/sequel/adapters/swift/mysql.rb +10 -12
- data/lib/sequel/adapters/swift/postgres.rb +13 -79
- data/lib/sequel/adapters/swift/sqlite.rb +9 -6
- data/lib/sequel/adapters/swift.rb +31 -27
- data/lib/sequel/adapters/tinytds.rb +177 -25
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +77 -0
- data/lib/sequel/adapters/utils/pg_types.rb +81 -0
- data/lib/sequel/adapters/utils/split_alter_table.rb +36 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
- data/lib/sequel/ast_transformer.rb +194 -0
- data/lib/sequel/connection_pool/sharded_single.rb +23 -13
- data/lib/sequel/connection_pool/sharded_threaded.rb +64 -13
- data/lib/sequel/connection_pool/single.rb +11 -3
- data/lib/sequel/connection_pool/threaded.rb +69 -20
- data/lib/sequel/connection_pool.rb +20 -18
- data/lib/sequel/core.rb +143 -11
- data/lib/sequel/database/connecting.rb +66 -29
- data/lib/sequel/database/dataset.rb +4 -4
- data/lib/sequel/database/dataset_defaults.rb +63 -2
- data/lib/sequel/database/logging.rb +7 -2
- data/lib/sequel/database/misc.rb +192 -51
- data/lib/sequel/database/query.rb +299 -114
- data/lib/sequel/database/schema_generator.rb +103 -36
- data/lib/sequel/database/schema_methods.rb +310 -69
- data/lib/sequel/dataset/actions.rb +344 -90
- data/lib/sequel/dataset/features.rb +101 -8
- data/lib/sequel/dataset/graph.rb +42 -15
- data/lib/sequel/dataset/misc.rb +52 -25
- data/lib/sequel/dataset/mutation.rb +12 -7
- data/lib/sequel/dataset/prepared_statements.rb +68 -30
- data/lib/sequel/dataset/query.rb +322 -68
- data/lib/sequel/dataset/sql.rb +716 -293
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/_pretty_table.rb +83 -0
- data/lib/sequel/extensions/arbitrary_servers.rb +109 -0
- data/lib/sequel/extensions/blank.rb +4 -0
- data/lib/sequel/extensions/columns_introspection.rb +72 -0
- data/lib/sequel/extensions/connection_validator.rb +109 -0
- data/lib/sequel/extensions/constraint_validations.rb +451 -0
- data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +30 -46
- data/lib/sequel/extensions/eval_inspect.rb +173 -0
- data/lib/sequel/extensions/inflector.rb +4 -0
- data/lib/sequel/extensions/looser_typecasting.rb +5 -4
- data/lib/sequel/extensions/migration.rb +100 -11
- data/lib/sequel/extensions/named_timezones.rb +9 -0
- data/lib/sequel/extensions/null_dataset.rb +94 -0
- data/lib/sequel/extensions/pagination.rb +4 -0
- data/lib/sequel/extensions/pg_array.rb +539 -0
- data/lib/sequel/extensions/pg_array_ops.rb +263 -0
- data/lib/sequel/extensions/pg_auto_parameterize.rb +175 -0
- data/lib/sequel/extensions/pg_hstore.rb +334 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +293 -0
- data/lib/sequel/extensions/pg_inet.rb +113 -0
- data/lib/sequel/extensions/pg_interval.rb +191 -0
- data/lib/sequel/extensions/pg_json.rb +212 -0
- data/lib/sequel/extensions/pg_range.rb +513 -0
- data/lib/sequel/extensions/pg_range_ops.rb +150 -0
- data/lib/sequel/extensions/pg_row.rb +576 -0
- data/lib/sequel/extensions/pg_row_ops.rb +182 -0
- data/lib/sequel/extensions/pg_statement_cache.rb +317 -0
- data/lib/sequel/extensions/pretty_table.rb +17 -72
- data/lib/sequel/extensions/query.rb +8 -4
- data/lib/sequel/extensions/query_literals.rb +79 -0
- data/lib/sequel/extensions/schema_caching.rb +76 -0
- data/lib/sequel/extensions/schema_dumper.rb +282 -76
- data/lib/sequel/extensions/select_remove.rb +39 -0
- data/lib/sequel/extensions/server_block.rb +140 -0
- data/lib/sequel/extensions/split_array_nil.rb +65 -0
- data/lib/sequel/extensions/sql_expr.rb +8 -110
- data/lib/sequel/extensions/string_date_time.rb +4 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +10 -4
- data/lib/sequel/extensions/to_dot.rb +99 -83
- data/lib/sequel/model/associations.rb +1263 -409
- data/lib/sequel/model/base.rb +624 -171
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +24 -2
- data/lib/sequel/model/inflections.rb +1 -1
- data/lib/sequel/model.rb +30 -11
- data/lib/sequel/no_core_ext.rb +2 -0
- data/lib/sequel/plugins/active_model.rb +13 -1
- data/lib/sequel/plugins/association_pks.rb +137 -16
- data/lib/sequel/plugins/caching.rb +25 -18
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/composition.rb +44 -12
- data/lib/sequel/plugins/constraint_validations.rb +198 -0
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/defaults_setter.rb +72 -0
- data/lib/sequel/plugins/dirty.rb +214 -0
- data/lib/sequel/plugins/eager_each.rb +59 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/hook_class_methods.rb +1 -1
- data/lib/sequel/plugins/identity_map.rb +134 -15
- data/lib/sequel/plugins/instance_filters.rb +10 -0
- data/lib/sequel/plugins/instance_hooks.rb +1 -1
- data/lib/sequel/plugins/json_serializer.rb +77 -6
- data/lib/sequel/plugins/list.rb +13 -2
- data/lib/sequel/plugins/many_through_many.rb +103 -51
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
- data/lib/sequel/plugins/nested_attributes.rb +150 -66
- data/lib/sequel/plugins/optimistic_locking.rb +8 -0
- data/lib/sequel/plugins/pg_row.rb +121 -0
- data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
- data/lib/sequel/plugins/prepared_statements.rb +168 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +87 -0
- data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
- data/lib/sequel/plugins/rcte_tree.rb +31 -17
- data/lib/sequel/plugins/schema.rb +8 -3
- data/lib/sequel/plugins/serialization.rb +98 -49
- data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
- data/lib/sequel/plugins/sharding.rb +21 -54
- data/lib/sequel/plugins/single_table_inheritance.rb +57 -12
- data/lib/sequel/plugins/static_cache.rb +99 -0
- data/lib/sequel/plugins/subclasses.rb +29 -3
- data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
- data/lib/sequel/plugins/timestamps.rb +1 -1
- data/lib/sequel/plugins/touch.rb +18 -6
- data/lib/sequel/plugins/tree.rb +3 -3
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +2 -2
- data/lib/sequel/plugins/validation_class_methods.rb +2 -1
- data/lib/sequel/plugins/validation_helpers.rb +57 -4
- data/lib/sequel/plugins/xml_serializer.rb +15 -4
- data/lib/sequel/sql.rb +721 -141
- data/lib/sequel/timezones.rb +67 -40
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/firebird_spec.rb +53 -39
- data/spec/adapters/mssql_spec.rb +261 -66
- data/spec/adapters/mysql_spec.rb +597 -352
- data/spec/adapters/oracle_spec.rb +92 -117
- data/spec/adapters/postgres_spec.rb +2103 -341
- data/spec/adapters/spec_helper.rb +16 -6
- data/spec/adapters/sqlite_spec.rb +237 -76
- data/spec/core/connection_pool_spec.rb +270 -141
- data/spec/core/database_spec.rb +980 -524
- data/spec/core/dataset_spec.rb +1658 -1243
- data/spec/core/expression_filters_spec.rb +741 -334
- data/spec/core/mock_adapter_spec.rb +453 -0
- data/spec/core/object_graph_spec.rb +88 -129
- data/spec/core/schema_generator_spec.rb +4 -4
- data/spec/core/schema_spec.rb +556 -53
- data/spec/core/spec_helper.rb +7 -48
- data/spec/core_extensions_spec.rb +626 -0
- data/spec/extensions/active_model_spec.rb +13 -0
- data/spec/extensions/arbitrary_servers_spec.rb +110 -0
- data/spec/extensions/association_autoreloading_spec.rb +18 -10
- data/spec/extensions/association_dependencies_spec.rb +15 -25
- data/spec/extensions/association_pks_spec.rb +227 -33
- data/spec/extensions/association_proxies_spec.rb +4 -4
- data/spec/extensions/boolean_readers_spec.rb +25 -25
- data/spec/extensions/caching_spec.rb +47 -51
- data/spec/extensions/class_table_inheritance_spec.rb +31 -83
- data/spec/extensions/columns_introspection_spec.rb +91 -0
- data/spec/extensions/composition_spec.rb +18 -13
- data/spec/extensions/connection_validator_spec.rb +118 -0
- data/spec/extensions/constraint_validations_plugin_spec.rb +196 -0
- data/spec/extensions/constraint_validations_spec.rb +316 -0
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +88 -0
- data/spec/extensions/dirty_spec.rb +155 -0
- data/spec/extensions/eager_each_spec.rb +34 -0
- data/spec/extensions/eval_inspect_spec.rb +67 -0
- data/spec/extensions/force_encoding_spec.rb +4 -2
- data/spec/extensions/hook_class_methods_spec.rb +97 -128
- data/spec/extensions/identity_map_spec.rb +142 -24
- data/spec/extensions/inflector_spec.rb +0 -4
- data/spec/extensions/instance_filters_spec.rb +11 -21
- data/spec/extensions/instance_hooks_spec.rb +72 -0
- data/spec/extensions/json_serializer_spec.rb +49 -12
- data/spec/extensions/lazy_attributes_spec.rb +16 -20
- data/spec/extensions/list_spec.rb +49 -40
- data/spec/extensions/looser_typecasting_spec.rb +7 -7
- data/spec/extensions/many_through_many_spec.rb +368 -254
- data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
- data/spec/extensions/migration_spec.rb +140 -35
- data/spec/extensions/named_timezones_spec.rb +29 -11
- data/spec/extensions/nested_attributes_spec.rb +268 -89
- data/spec/extensions/null_dataset_spec.rb +85 -0
- data/spec/extensions/optimistic_locking_spec.rb +24 -21
- data/spec/extensions/pg_array_ops_spec.rb +112 -0
- data/spec/extensions/pg_array_spec.rb +324 -0
- data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
- data/spec/extensions/pg_hstore_ops_spec.rb +140 -0
- data/spec/extensions/pg_hstore_spec.rb +200 -0
- data/spec/extensions/pg_inet_spec.rb +47 -0
- data/spec/extensions/pg_interval_spec.rb +72 -0
- data/spec/extensions/pg_json_spec.rb +99 -0
- data/spec/extensions/pg_range_ops_spec.rb +56 -0
- data/spec/extensions/pg_range_spec.rb +395 -0
- data/spec/extensions/pg_row_ops_spec.rb +58 -0
- data/spec/extensions/pg_row_plugin_spec.rb +49 -0
- data/spec/extensions/pg_row_spec.rb +340 -0
- data/spec/extensions/pg_statement_cache_spec.rb +208 -0
- data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
- data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
- data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
- data/spec/extensions/prepared_statements_spec.rb +87 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
- data/spec/extensions/pretty_table_spec.rb +7 -6
- data/spec/extensions/query_literals_spec.rb +167 -0
- data/spec/extensions/query_spec.rb +9 -3
- data/spec/extensions/rcte_tree_spec.rb +50 -43
- data/spec/extensions/schema_caching_spec.rb +41 -0
- data/spec/extensions/schema_dumper_spec.rb +434 -49
- data/spec/extensions/schema_spec.rb +30 -49
- data/spec/extensions/select_remove_spec.rb +38 -0
- data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
- data/spec/extensions/serialization_spec.rb +86 -48
- data/spec/extensions/server_block_spec.rb +90 -0
- data/spec/extensions/sharding_spec.rb +69 -143
- data/spec/extensions/single_table_inheritance_spec.rb +65 -29
- data/spec/extensions/skip_create_refresh_spec.rb +1 -1
- data/spec/extensions/spec_helper.rb +34 -67
- data/spec/extensions/split_array_nil_spec.rb +24 -0
- data/spec/extensions/sql_expr_spec.rb +29 -60
- data/spec/extensions/static_cache_spec.rb +145 -0
- data/spec/extensions/subclasses_spec.rb +14 -0
- data/spec/extensions/tactical_eager_loading_spec.rb +17 -19
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/timestamps_spec.rb +6 -6
- data/spec/extensions/to_dot_spec.rb +8 -11
- data/spec/extensions/touch_spec.rb +53 -14
- data/spec/extensions/tree_spec.rb +11 -26
- data/spec/extensions/typecast_on_load_spec.rb +9 -6
- data/spec/extensions/update_primary_key_spec.rb +30 -24
- data/spec/extensions/validation_class_methods_spec.rb +77 -68
- data/spec/extensions/validation_helpers_spec.rb +48 -37
- data/spec/extensions/xml_serializer_spec.rb +29 -4
- data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
- data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
- data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
- data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
- data/spec/integration/associations_test.rb +659 -21
- data/spec/integration/database_test.rb +25 -5
- data/spec/integration/dataset_test.rb +729 -141
- data/spec/integration/eager_loader_test.rb +38 -54
- data/spec/integration/migrator_test.rb +2 -3
- data/spec/integration/model_test.rb +81 -2
- data/spec/integration/plugin_test.rb +871 -160
- data/spec/integration/prepared_statement_test.rb +272 -128
- data/spec/integration/schema_test.rb +377 -57
- data/spec/integration/spec_helper.rb +49 -32
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +183 -8
- data/spec/integration/type_test.rb +40 -8
- data/spec/model/association_reflection_spec.rb +207 -8
- data/spec/model/associations_spec.rb +1206 -693
- data/spec/model/base_spec.rb +334 -100
- data/spec/model/dataset_methods_spec.rb +45 -27
- data/spec/model/eager_loading_spec.rb +828 -692
- data/spec/model/hooks_spec.rb +355 -67
- data/spec/model/model_spec.rb +251 -179
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +506 -232
- data/spec/model/spec_helper.rb +16 -77
- data/spec/model/validations_spec.rb +38 -2
- data/spec/rcov.opts +2 -0
- metadata +223 -81
- data/spec/core/core_sql_spec.rb +0 -451
data/doc/association_basics.rdoc
CHANGED
|
@@ -247,7 +247,7 @@ example is a tree structure:
|
|
|
247
247
|
|
|
248
248
|
class Node
|
|
249
249
|
many_to_one :parent, :class=>self
|
|
250
|
-
one_to_many :children :key=>:parent_id, :class=>self
|
|
250
|
+
one_to_many :children, :key=>:parent_id, :class=>self
|
|
251
251
|
end
|
|
252
252
|
|
|
253
253
|
For many_to_many self_referential associations, it's fairly similar. Here's
|
|
@@ -293,32 +293,6 @@ Examples:
|
|
|
293
293
|
@artist.remove_album(@album)
|
|
294
294
|
@artist.remove_all_albums
|
|
295
295
|
|
|
296
|
-
== Dataset Method
|
|
297
|
-
|
|
298
|
-
In addition to the above methods, associations also add a instance method
|
|
299
|
-
ending in +_dataset+ that returns a dataset representing the objects in the associated table:
|
|
300
|
-
|
|
301
|
-
@album.artist_id
|
|
302
|
-
# 10
|
|
303
|
-
@album.artist_dataset
|
|
304
|
-
# SELECT * FROM artists WHERE (id = 10)
|
|
305
|
-
|
|
306
|
-
@artist.id
|
|
307
|
-
# 20
|
|
308
|
-
@artist.albums_dataset
|
|
309
|
-
# SELECT * FROM albums WHERE (artist_id = 20)
|
|
310
|
-
|
|
311
|
-
The association dataset is just like any other Sequel dataset, in that
|
|
312
|
-
it can be further filtered, ordered, etc.:
|
|
313
|
-
|
|
314
|
-
@artist.albums_dataset.
|
|
315
|
-
filter(:name.like('A%')).
|
|
316
|
-
order(:copies_sold).
|
|
317
|
-
limit(10)
|
|
318
|
-
# SELECT * FROM albums
|
|
319
|
-
# WHERE ((artist_id = 20) AND (name LIKE 'A%'))
|
|
320
|
-
# ORDER BY copies_sold LIMIT 10
|
|
321
|
-
|
|
322
296
|
== Caching
|
|
323
297
|
|
|
324
298
|
Associations are cached after being retrieved:
|
|
@@ -352,23 +326,155 @@ instance method:
|
|
|
352
326
|
@album.artists # [<Artist ...>, ...]
|
|
353
327
|
@album.associations[:artists] # [<Artist ...>, ...]
|
|
354
328
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
329
|
+
== Dataset Method
|
|
330
|
+
|
|
331
|
+
In addition to the above methods, associations also add a instance method
|
|
332
|
+
ending in +_dataset+ that returns a dataset representing the objects in the associated table:
|
|
333
|
+
|
|
334
|
+
@album.artist_id
|
|
335
|
+
# 10
|
|
336
|
+
@album.artist_dataset
|
|
337
|
+
# SELECT * FROM artists WHERE (id = 10)
|
|
338
|
+
|
|
339
|
+
@artist.id
|
|
340
|
+
# 20
|
|
341
|
+
@artist.albums_dataset
|
|
342
|
+
# SELECT * FROM albums WHERE (artist_id = 20)
|
|
343
|
+
|
|
344
|
+
The association dataset is just like any other Sequel dataset, in that
|
|
345
|
+
it can be further filtered, ordered, etc.:
|
|
346
|
+
|
|
347
|
+
@artist.albums_dataset.
|
|
348
|
+
where(Sequel.like(:name, 'A%')).
|
|
349
|
+
order(:copies_sold).
|
|
350
|
+
limit(10)
|
|
351
|
+
# SELECT * FROM albums
|
|
352
|
+
# WHERE ((artist_id = 20) AND (name LIKE 'A%'))
|
|
353
|
+
# ORDER BY copies_sold LIMIT 10
|
|
354
|
+
|
|
355
|
+
Records retrieved using the +_dataset+ method are not cached in the
|
|
356
|
+
associations cache.
|
|
358
357
|
|
|
359
358
|
@album.artists_dataset.all # [<Artist ...>, ...]
|
|
360
359
|
@album.associations[:artists] # nil
|
|
361
360
|
|
|
361
|
+
== Dynamic Association Modification
|
|
362
|
+
|
|
363
|
+
Similar to the +_dataset+ method, you can provide a block to the association
|
|
364
|
+
method to customize the dataset that will be used to retrieve the records. So
|
|
365
|
+
you can apply a filter in either of these two ways:
|
|
366
|
+
|
|
367
|
+
@artist.albums_dataset.where(Sequel.like(:name, 'A%'))
|
|
368
|
+
@artist.albums{|ds| ds.where(Sequel.like(:name, 'A%'))}
|
|
369
|
+
|
|
370
|
+
While they both apply the same filter, using the +_dataset+ method does not
|
|
371
|
+
apply any of the association callbacks or handle association reciprocals (see
|
|
372
|
+
below for details about callbacks and reciprocals). Using a block instead handles
|
|
373
|
+
all those things, and also caches its results in the associations cache (ignoring
|
|
374
|
+
any previously cached value).
|
|
375
|
+
|
|
376
|
+
== Filtering By Associations
|
|
377
|
+
|
|
378
|
+
In addition to using the association method to get associated objects, you
|
|
379
|
+
can also use associated objects in filters. For example, to get
|
|
380
|
+
all albums for a given artist, you would usually do:
|
|
381
|
+
|
|
382
|
+
@artist.albums
|
|
383
|
+
# or @artist.albums_dataset for a dataset
|
|
384
|
+
|
|
385
|
+
You can also do the following:
|
|
386
|
+
|
|
387
|
+
Album.where(:artist=>@artist).all
|
|
388
|
+
# or leave off the .all for a dataset
|
|
389
|
+
|
|
390
|
+
For filtering by a single association, this isn't very useful. However, unlike
|
|
391
|
+
using the association method, using a filter allows you to filter by multiple
|
|
392
|
+
associations:
|
|
393
|
+
|
|
394
|
+
Album.where(:artist=>@artist, :publisher=>@publisher)
|
|
395
|
+
|
|
396
|
+
This will return all albums by that artist and published by that publisher.
|
|
397
|
+
This isn't possible using just the association method approach, though you
|
|
398
|
+
can combine the approaches:
|
|
399
|
+
|
|
400
|
+
@artist.albums_dataset.where(:publisher=>@publisher)
|
|
401
|
+
|
|
402
|
+
This doesn't just work for +many_to_one+ associations, it also works for
|
|
403
|
+
+one_to_one+, +one_to_many+, and +many_to_many+ associations:
|
|
404
|
+
|
|
405
|
+
Album.one_to_one :album_info
|
|
406
|
+
# The album related to that AlbumInfo instance
|
|
407
|
+
Album.where(:album_info=>AlbumInfo[2])
|
|
408
|
+
|
|
409
|
+
Album.one_to_many :tracks
|
|
410
|
+
# The album related to that Track instance
|
|
411
|
+
Album.where(:tracks=>Track[3])
|
|
412
|
+
|
|
413
|
+
Album.many_to_many :tags
|
|
414
|
+
# All albums related to that Tag instance
|
|
415
|
+
Album.where(:tags=>Tag[4])
|
|
416
|
+
|
|
417
|
+
Note that for +one_to_many+ and +many_to_many+ associations, you still
|
|
418
|
+
use the plural form even though only a single model object is given.
|
|
419
|
+
|
|
420
|
+
You can also exclude by associations:
|
|
421
|
+
|
|
422
|
+
Album.exclude(:artist=>@artist).all
|
|
423
|
+
|
|
424
|
+
This will return all albums not by that artist.
|
|
425
|
+
|
|
426
|
+
You can also provide an array with multiple model objects:
|
|
427
|
+
|
|
428
|
+
Album.where(:artist=>[@artist1, @artist2]).all
|
|
429
|
+
|
|
430
|
+
Similar to using an array of integers or strings, this will return
|
|
431
|
+
all albums whose artist is one of those two artists. You can also
|
|
432
|
+
use +exclude+ if you want all albums not by either of those artists:
|
|
433
|
+
|
|
434
|
+
Album.exclude(:artist=>[@artist1, @artist2]).all
|
|
435
|
+
|
|
436
|
+
If you are using a +one_to_many+ or +many_to_many+ association, you
|
|
437
|
+
may want to return records where the records matches all of multiple
|
|
438
|
+
records, instead of matching any of them. For example:
|
|
439
|
+
|
|
440
|
+
Album.where(:tags=>[@tag1, @tag2])
|
|
441
|
+
|
|
442
|
+
This matches albums that are associated with either @tag1 or @tag2 or
|
|
443
|
+
both. If you only want ones that you are associated with both, you can
|
|
444
|
+
use separate filter calls:
|
|
445
|
+
|
|
446
|
+
Album.where(:tags=>@tag1).where(:tags=>@tag2)
|
|
447
|
+
|
|
448
|
+
Or the the array form of condition specifiers:
|
|
449
|
+
|
|
450
|
+
Album.where([[:tags, @tag1], [:tags, @tag2]])
|
|
451
|
+
|
|
452
|
+
These will return albums associated with both @tag1 and @tag2.
|
|
453
|
+
|
|
454
|
+
You can also provide a dataset value when filtering by associations:
|
|
455
|
+
|
|
456
|
+
Album.where(:artist=>Artist.where(Sequel.like(:name, 'A%'))).all
|
|
457
|
+
|
|
458
|
+
This will return all albums whose artist starts with 'A'. Like
|
|
459
|
+
the other forms, this can be inverted:
|
|
460
|
+
|
|
461
|
+
Album.exclude(:artist=>Artist.where(Sequel.like(:name, 'A%'))).all
|
|
462
|
+
|
|
463
|
+
This will return all albums whose artist does not start with 'A'.
|
|
464
|
+
|
|
465
|
+
Note that filtering by associations only works correctly for simple
|
|
466
|
+
associations (ones without conditions).
|
|
467
|
+
|
|
362
468
|
== Name Collisions
|
|
363
469
|
|
|
364
470
|
Because associations create instance methods, it's possible to override
|
|
365
|
-
existing instance methods if you name an
|
|
471
|
+
existing instance methods if you name an association the same as an
|
|
366
472
|
existing method. For example, <tt>values</tt> and <tt>associations</tt>
|
|
367
473
|
would be bad association names.
|
|
368
474
|
|
|
369
475
|
== Database Schema
|
|
370
476
|
|
|
371
|
-
Creating an association
|
|
477
|
+
Creating an association doesn't modify the database schema. Sequel
|
|
372
478
|
assumes your associations reflect the existing database schema. If not,
|
|
373
479
|
you should modify your schema before creating the associations.
|
|
374
480
|
|
|
@@ -451,6 +557,8 @@ wanted to add an albums_artists join table to create the following schema:
|
|
|
451
557
|
|
|
452
558
|
You could use the following Sequel code:
|
|
453
559
|
|
|
560
|
+
DB.create_join_table(:album_id=>:albums, :artist_id=>:artists)
|
|
561
|
+
# or
|
|
454
562
|
DB.create_table(:albums_artists) do
|
|
455
563
|
foreign_key :album_id, :albums
|
|
456
564
|
foreign_key :artist_id, :artists
|
|
@@ -499,6 +607,19 @@ To fix this, you need to specify the full model class name using the
|
|
|
499
607
|
end
|
|
500
608
|
end
|
|
501
609
|
|
|
610
|
+
If both classes are in the same module, but the default class name
|
|
611
|
+
used is not correct, you need to specify the full class name with the
|
|
612
|
+
:class option:
|
|
613
|
+
|
|
614
|
+
module App1
|
|
615
|
+
class AlbumArtist < Sequel::Model
|
|
616
|
+
one_to_many :albums
|
|
617
|
+
end
|
|
618
|
+
class Album < Sequel::Model
|
|
619
|
+
many_to_one :artist, :class=>"App1::AlbumArtist"
|
|
620
|
+
end
|
|
621
|
+
end
|
|
622
|
+
|
|
502
623
|
== Method Details
|
|
503
624
|
|
|
504
625
|
In all of these methods, _association_ is replaced by the symbol you
|
|
@@ -606,7 +727,7 @@ The <i>association</i>_dataset method returns a dataset that represents
|
|
|
606
727
|
all associated objects. This dataset is like any other Sequel dataset,
|
|
607
728
|
in that it can be filtered, ordered, etc.:
|
|
608
729
|
|
|
609
|
-
ds = @artist.albums_dataset.
|
|
730
|
+
ds = @artist.albums_dataset.where(Sequel.like(:name, 'A%')).order(:copies_sold)
|
|
610
731
|
|
|
611
732
|
Unlike most other Sequel datasets, association datasets have a couple of
|
|
612
733
|
added methods:
|
|
@@ -717,7 +838,7 @@ that returns all albums of an artist that went gold (sold at least
|
|
|
717
838
|
500,000 copies):
|
|
718
839
|
|
|
719
840
|
Artist.one_to_many :gold_albums, :class=>:Album do |ds|
|
|
720
|
-
ds.
|
|
841
|
+
ds.where{copies_sold > 500000}
|
|
721
842
|
end
|
|
722
843
|
|
|
723
844
|
==== :class
|
|
@@ -736,7 +857,7 @@ default class guessed will be wrong:
|
|
|
736
857
|
|
|
737
858
|
# guesses GoldAlbum
|
|
738
859
|
Artist.one_to_many :gold_albums do |ds|
|
|
739
|
-
ds.
|
|
860
|
+
ds.where{copies_sold > 500000}
|
|
740
861
|
end
|
|
741
862
|
|
|
742
863
|
You can specify the :class option using the class itself, a Symbol,
|
|
@@ -761,13 +882,13 @@ symbol. Defaults to :"#{self.name.underscore}_id".
|
|
|
761
882
|
|
|
762
883
|
Artist.one_to_many :albums # :key=>:artist_id
|
|
763
884
|
|
|
764
|
-
In both cases an array of symbols for a composite key association:
|
|
885
|
+
In both cases an array of symbols can be used for a composite key association:
|
|
765
886
|
|
|
766
887
|
Apartment.many_to_one :building # :key=>[:city, :address]
|
|
767
888
|
|
|
768
889
|
==== :conditions
|
|
769
890
|
|
|
770
|
-
The conditions to use to filter the association, can be any argument passed to
|
|
891
|
+
The conditions to use to filter the association, can be any argument passed to +where+.
|
|
771
892
|
If you use a hash or an array of two element arrays, this will also be used as a
|
|
772
893
|
filter when using eager_graph to load the association.
|
|
773
894
|
|
|
@@ -800,7 +921,7 @@ columns that have the same name in both the join table and the associated
|
|
|
800
921
|
table. Example:
|
|
801
922
|
|
|
802
923
|
Artist.one_to_many :albums, :select=>[:id, :name]
|
|
803
|
-
Album.many_to_many :tags, :select=>[:tags.*, :albums_tags__number]
|
|
924
|
+
Album.many_to_many :tags, :select=>[Sequel.expr(:tags).*, :albums_tags__number]
|
|
804
925
|
|
|
805
926
|
==== :limit
|
|
806
927
|
|
|
@@ -817,8 +938,6 @@ Use an array with two arguments for the value to specify a limit and an offset.
|
|
|
817
938
|
This probably doesn't make a lot of sense for *_to_one associations, though you
|
|
818
939
|
could use it to specify an offset.
|
|
819
940
|
|
|
820
|
-
This option is ignored when eager loading.
|
|
821
|
-
|
|
822
941
|
==== :join_table [+many_to_many+]
|
|
823
942
|
|
|
824
943
|
Name of table that includes the foreign keys to both the current model and the
|
|
@@ -833,7 +952,7 @@ Here's an example of the defaults:
|
|
|
833
952
|
==== :left_key [+many_to_many+]
|
|
834
953
|
|
|
835
954
|
Foreign key in join table that points to current model's primary key, as a
|
|
836
|
-
symbol. Defaults to :"#{
|
|
955
|
+
symbol. Defaults to :"#{model_name.underscore}_id".
|
|
837
956
|
|
|
838
957
|
Album.many_to_many :tags # :left_key=>:album_id
|
|
839
958
|
|
|
@@ -842,9 +961,9 @@ Can use an array of symbols for a composite key association.
|
|
|
842
961
|
==== :right_key [+many_to_many+]
|
|
843
962
|
|
|
844
963
|
Foreign key in join table that points to associated model's primary key, as a
|
|
845
|
-
symbol. Defaults to :"#{
|
|
964
|
+
symbol. Defaults to :"#{association_name.singularize}_id".
|
|
846
965
|
|
|
847
|
-
Album.many_to_many :tags # :
|
|
966
|
+
Album.many_to_many :tags # :right_key=>:tag_id
|
|
848
967
|
|
|
849
968
|
Can use an array of symbols for a composite key association.
|
|
850
969
|
|
|
@@ -895,7 +1014,7 @@ Here's an example of an association of songs to artists through lyrics, where
|
|
|
895
1014
|
the artist can perform any one of four tasks for the lyric:
|
|
896
1015
|
|
|
897
1016
|
Album.one_to_many :songs, :dataset=>(proc do
|
|
898
|
-
Song.
|
|
1017
|
+
Song.select_all(:songs).
|
|
899
1018
|
join(Lyric, :id=>:lyricid,
|
|
900
1019
|
id=>[:composer_id, :arranger_id, :vocalist_id, :lyricist_id])
|
|
901
1020
|
end)
|
|
@@ -914,8 +1033,8 @@ set up association extensions. For more information , please see the
|
|
|
914
1033
|
==== :primary_key
|
|
915
1034
|
|
|
916
1035
|
The column that the :key option references, as a symbol. For +many_to_one+
|
|
917
|
-
associations, this column in the associated table. For +one_to_one+ and
|
|
918
|
-
+one_to_many+ associations, this column in the current table. In both cases,
|
|
1036
|
+
associations, this column is in the associated table. For +one_to_one+ and
|
|
1037
|
+
+one_to_many+ associations, this column is in the current table. In both cases,
|
|
919
1038
|
it defaults to the primary key of the table. Can use an
|
|
920
1039
|
array of symbols for a composite key association.
|
|
921
1040
|
|
|
@@ -939,7 +1058,7 @@ Column in associated table that :right_key points to, as a symbol.
|
|
|
939
1058
|
Defaults to primary key of the associated table.
|
|
940
1059
|
|
|
941
1060
|
Tag.set_primary_key :tid
|
|
942
|
-
Album.many_to_many :tags # :
|
|
1061
|
+
Album.many_to_many :tags # :right_primary_key=>:tid
|
|
943
1062
|
|
|
944
1063
|
Can use an array of symbols for a composite key association.
|
|
945
1064
|
|
|
@@ -952,7 +1071,7 @@ applies to the join table. It can be used to make sure additional columns are
|
|
|
952
1071
|
used when inserting, or that filters are used when deleting.
|
|
953
1072
|
|
|
954
1073
|
Artist.many_to_many :lead_guitar_albums, :join_table_block=>proc do |ds|
|
|
955
|
-
ds.
|
|
1074
|
+
ds.where(:instrument_id=>5).set_overrides(:instrument_id=>5)
|
|
956
1075
|
end
|
|
957
1076
|
|
|
958
1077
|
=== Callback Options
|
|
@@ -1024,8 +1143,6 @@ Called after removing an object from the association:
|
|
|
1024
1143
|
|
|
1025
1144
|
Called before the _<i>association</i>= method is called to modify the objects:
|
|
1026
1145
|
|
|
1027
|
-
Called before removing an object from the association:
|
|
1028
|
-
|
|
1029
1146
|
class Album
|
|
1030
1147
|
# Don't associate the album with an artist if the year the album was
|
|
1031
1148
|
# released is less than the year the artist/band started.
|
|
@@ -1049,13 +1166,12 @@ Called after the _<i>association</i>= method is called to modify the objects:
|
|
|
1049
1166
|
|
|
1050
1167
|
==== :after_load
|
|
1051
1168
|
|
|
1052
|
-
Called after retrieving the associated records from the database.
|
|
1053
|
-
when eager loading via eager_graph, but called when eager loading via eager.
|
|
1169
|
+
Called after retrieving the associated records from the database.
|
|
1054
1170
|
|
|
1055
1171
|
class Artist
|
|
1056
1172
|
# Cache all album names to a single string when retrieving the
|
|
1057
1173
|
# albums.
|
|
1058
|
-
one_to_many :albums, :
|
|
1174
|
+
one_to_many :albums, :after_load=>:cache_album_names
|
|
1059
1175
|
|
|
1060
1176
|
attr_reader :album_names
|
|
1061
1177
|
|
|
@@ -1067,8 +1183,7 @@ when eager loading via eager_graph, but called when eager loading via eager.
|
|
|
1067
1183
|
end
|
|
1068
1184
|
|
|
1069
1185
|
Generally used if you know you will always want a certain action done
|
|
1070
|
-
when retrieving the association.
|
|
1071
|
-
also plan on using eager_graph to eagerly load the association.
|
|
1186
|
+
when retrieving the association.
|
|
1072
1187
|
|
|
1073
1188
|
For +one_to_many+ and +many_to_many+ associations, both the argument to
|
|
1074
1189
|
symbol callbacks and the second argument to proc callbacks will be an
|
|
@@ -1112,13 +1227,9 @@ For many details and examples of custom eager loaders, please see the
|
|
|
1112
1227
|
==== :eager_loader_key
|
|
1113
1228
|
|
|
1114
1229
|
A symbol for the key column to use to populate the key hash for the eager
|
|
1115
|
-
loader.
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
eagerly load any associated objects for that association. If you have a
|
|
1119
|
-
custom eager loader and aren't sure of a good value to use here, and you
|
|
1120
|
-
aren't using the key_hash (first argument to the eager_loader proc), then
|
|
1121
|
-
you can probably use the primary key column of the model.
|
|
1230
|
+
loader. Generally does not need to be set manually, defaults to the key
|
|
1231
|
+
method used. Can be set to nil to not populate the key hash (better for
|
|
1232
|
+
performance if a custom eager loader does not use the key_hash).
|
|
1122
1233
|
|
|
1123
1234
|
==== :eager_block
|
|
1124
1235
|
|
|
@@ -1137,7 +1248,7 @@ association based on dependent associations:
|
|
|
1137
1248
|
|
|
1138
1249
|
Artist.one_to_many :albums_with_short_tracks, :class=>:Album,
|
|
1139
1250
|
:eager_graph=>:tracks do |ds|
|
|
1140
|
-
ds.
|
|
1251
|
+
ds.where{tracks__seconds < 120}
|
|
1141
1252
|
end
|
|
1142
1253
|
Artist.one_to_many :albums_by_track_name, :class=>:Album,
|
|
1143
1254
|
:eager_graph=>:tracks do |ds|
|
|
@@ -1169,13 +1280,13 @@ via eager_graph. This is useful to specify conditions that can't be specified
|
|
|
1169
1280
|
in a hash or array of two element arrays.
|
|
1170
1281
|
|
|
1171
1282
|
Artist.one_to_many :gold_albums, :class=>:Album,
|
|
1172
|
-
:graph_block=>proc{|j,lj,js|
|
|
1283
|
+
:graph_block=>proc{|j,lj,js| Sequel.qualify(j, :copies_sold) > 500000}
|
|
1173
1284
|
|
|
1174
1285
|
==== :graph_join_type
|
|
1175
1286
|
|
|
1176
1287
|
The type of SQL join to use when eagerly loading the association via
|
|
1177
1288
|
eager_graph. Defaults to :left_outer. This is useful if you want to
|
|
1178
|
-
ensure that
|
|
1289
|
+
ensure that only artists that have albums are returned:
|
|
1179
1290
|
|
|
1180
1291
|
Artist.one_to_many :albums, :graph_join_type=>:inner
|
|
1181
1292
|
# Will exclude artists without an album
|
|
@@ -1201,8 +1312,8 @@ where the artist's name differs in case:
|
|
|
1201
1312
|
|
|
1202
1313
|
Artist.one_to_many :albums, :key=>:artist_name,
|
|
1203
1314
|
:graph_only_conditions=>nil,
|
|
1204
|
-
:graph_block=>proc{|j,lj,js| {:lower.
|
|
1205
|
-
:lower.
|
|
1315
|
+
:graph_block=>proc{|j,lj,js| {Sequel.function(:lower, Sequel.qualify(j, :artist_name))=>
|
|
1316
|
+
Sequel.function(:lower, Sequel.qualify(lj, :name))}}
|
|
1206
1317
|
|
|
1207
1318
|
Note how :graph_only_conditions is set to nil to ignore any existing conditions,
|
|
1208
1319
|
and :graph_block is used to set up the case insensitive comparison.
|
|
@@ -1218,25 +1329,46 @@ a JOIN USING or NATURAL JOIN for the graph:
|
|
|
1218
1329
|
Artist.one_to_many :albums, :key=>:artist_name,
|
|
1219
1330
|
:graph_only_conditions=>nil, :graph_join_type=>:natural
|
|
1220
1331
|
|
|
1332
|
+
==== :graph_alias_base
|
|
1333
|
+
|
|
1334
|
+
The base name to use for the table alias when eager graphing. Defaults to the name
|
|
1335
|
+
of the association. If the alias name has already been used in the query, Sequel will create
|
|
1336
|
+
a unique alias by appending a numeric suffix (e.g. alias_0, alias_1, ...) until the alias is
|
|
1337
|
+
unique.
|
|
1338
|
+
|
|
1339
|
+
This is mostly useful if you have associations with the same name in many models, and you want
|
|
1340
|
+
to be able to easily tell which table alias corresponds to which association when eagerly
|
|
1341
|
+
graphing multiple associations with the same name.
|
|
1342
|
+
|
|
1343
|
+
You can override this option on a per-graph basis by specifying the association as an
|
|
1344
|
+
SQL::AliasedExpression instead of a symbol:
|
|
1345
|
+
|
|
1346
|
+
Album.eager_graph(Sequel.as(:artist, :a))
|
|
1347
|
+
|
|
1221
1348
|
==== :eager_grapher
|
|
1222
1349
|
|
|
1223
1350
|
Sets up a custom grapher to use when eager loading the objects via eager_graph.
|
|
1224
|
-
This is the eager_graph analogue to the :eager_loader option.
|
|
1351
|
+
This is the eager_graph analogue to the :eager_loader option. This isn't generally
|
|
1352
|
+
needed, as one of the other eager_graph related association options is usually sufficient.
|
|
1225
1353
|
|
|
1226
|
-
If specified, should be a proc that accepts
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1354
|
+
If specified, should be a proc that accepts a single hash argument, which will contain
|
|
1355
|
+
at least the following keys:
|
|
1356
|
+
|
|
1357
|
+
:self :: The dataset that is doing the eager loading
|
|
1358
|
+
:table_alias :: An alias to use for the table to graph for this association.
|
|
1359
|
+
:implicit_qualifier :: The alias that was used for the current table (since you can cascade associations).
|
|
1360
|
+
:callback :: A callback proc used to dynamically modify the dataset to graph into the
|
|
1361
|
+
current dataset, before such graphing is done. This is nil if no callback
|
|
1362
|
+
proc is used.
|
|
1363
|
+
|
|
1364
|
+
Example:
|
|
1230
1365
|
|
|
1231
1366
|
Artist.one_to_many :self_title_albums, :class=>:Album,
|
|
1232
|
-
:eager_grapher=>(proc do |
|
|
1233
|
-
|
|
1234
|
-
:table_alias=>
|
|
1367
|
+
:eager_grapher=>(proc do |eo|
|
|
1368
|
+
eo[:self].graph(Album, {:artist_id=>:id, :name=>:name},
|
|
1369
|
+
:table_alias=>eo[:table_alias], :implicit_qualifier=>eo[:implicit_qualifier])
|
|
1235
1370
|
end)
|
|
1236
1371
|
|
|
1237
|
-
This isn't generally needed, as one of the other eager_graph related
|
|
1238
|
-
association options is usually sufficient.
|
|
1239
|
-
|
|
1240
1372
|
==== :order_eager_graph
|
|
1241
1373
|
|
|
1242
1374
|
Whether to add the order to the dataset's order when graphing via eager_graph.
|
|
@@ -1278,7 +1410,7 @@ has received a bachelor's degree (degree starting with B):
|
|
|
1278
1410
|
|
|
1279
1411
|
Person.many_to_many :bachelor_degree_colleges, :class=>:College,
|
|
1280
1412
|
:join_table=>:degrees_received,
|
|
1281
|
-
:graph_join_table_block=>proc{|j,lj,js|
|
|
1413
|
+
:graph_join_table_block=>proc{|j,lj,js| Sequel.qualify(j, :degree).like('B%')}
|
|
1282
1414
|
|
|
1283
1415
|
This should be done when graphing the join table, instead of when graphing the
|
|
1284
1416
|
final table, as :degree is a column of the join table.
|
|
@@ -1300,6 +1432,74 @@ by the foreign/primary keys. This option causes the
|
|
|
1300
1432
|
you want to replace the default foreign/primary key conditions that Sequel
|
|
1301
1433
|
would use when eagerly graphing.
|
|
1302
1434
|
|
|
1435
|
+
=== Column Naming Conflict Options
|
|
1436
|
+
|
|
1437
|
+
Sequel's association support historically called methods on model objects
|
|
1438
|
+
to get primary key or foreign key values instead of accessing the column
|
|
1439
|
+
values directly, in order to allow advanced features such as associations
|
|
1440
|
+
based on virtual column keys. Unfortunately, that causes issues if columns
|
|
1441
|
+
are used with names that clash with existing method names, which can happen
|
|
1442
|
+
if you want to name the association the same name as an existing column, or
|
|
1443
|
+
if the column has the same name as an already defined method such as
|
|
1444
|
+
<tt>object_id</tt>.
|
|
1445
|
+
|
|
1446
|
+
Sequel has added the following options that allow you to work around the
|
|
1447
|
+
issue by either specifying the column name symbol or the method name symbol
|
|
1448
|
+
to use. In most cases, these methods are designed to be used with column
|
|
1449
|
+
aliases defined with <tt>Model.def_column_alias</tt>:
|
|
1450
|
+
|
|
1451
|
+
# Example schema:
|
|
1452
|
+
# albums artists
|
|
1453
|
+
# :id /--> :id
|
|
1454
|
+
# :artist --/ :name
|
|
1455
|
+
# :name
|
|
1456
|
+
class Album < Sequel::Model
|
|
1457
|
+
def_column_alias(:artist_id, :artist)
|
|
1458
|
+
many_to_one :artist, :key=>:artist_id, :key_column=>:artist
|
|
1459
|
+
end
|
|
1460
|
+
|
|
1461
|
+
# Example schema:
|
|
1462
|
+
# things objs
|
|
1463
|
+
# :id /--> :id
|
|
1464
|
+
# :object_id --/ :name
|
|
1465
|
+
# :name
|
|
1466
|
+
class Thing < Sequel::Model
|
|
1467
|
+
def_column_alias(:obj_id, :object_id)
|
|
1468
|
+
end
|
|
1469
|
+
class Obj < Sequel::Model
|
|
1470
|
+
one_to_many :things, :key=>:object_id, :key_method=>:obj_id
|
|
1471
|
+
end
|
|
1472
|
+
|
|
1473
|
+
==== :key_column [+many_to_one+]
|
|
1474
|
+
|
|
1475
|
+
Like the :key option, but :key references the method name, while
|
|
1476
|
+
:key_column references the underlying column.
|
|
1477
|
+
|
|
1478
|
+
==== :primary_key_method [+many_to_one+]
|
|
1479
|
+
|
|
1480
|
+
Like the :primary_key option, but :primary_key references the column
|
|
1481
|
+
name, while :primary_key_method references the method name.
|
|
1482
|
+
|
|
1483
|
+
==== :primary_key_column [+one_to_many+, +one_to_one+]
|
|
1484
|
+
|
|
1485
|
+
Like the :primary_key option, but :primary_key references the method name, while
|
|
1486
|
+
:primary_key_column references the underlying column.
|
|
1487
|
+
|
|
1488
|
+
==== :key_method [+one_to_many+, +one_to_one+]
|
|
1489
|
+
|
|
1490
|
+
Like the :key option, but :key references the column
|
|
1491
|
+
name, while :key_method references the method name.
|
|
1492
|
+
|
|
1493
|
+
==== :left_primary_key_column [+many_to_many+]
|
|
1494
|
+
|
|
1495
|
+
Like the :left_primary_key option, but :left_primary_key references the method name, while
|
|
1496
|
+
:left_primary_key_column references the underlying column.
|
|
1497
|
+
|
|
1498
|
+
==== :right_primary_key_method [+many_to_many+]
|
|
1499
|
+
|
|
1500
|
+
Like the :right_primary_key option, but :right_primary_key references the column
|
|
1501
|
+
name, while :right_primary_key_method references the method name.
|
|
1502
|
+
|
|
1303
1503
|
=== Advanced Options
|
|
1304
1504
|
|
|
1305
1505
|
==== :reciprocal
|
|
@@ -1399,3 +1599,51 @@ associations depends on another plugin that defines instance methods of
|
|
|
1399
1599
|
the same name. In that case, the instance methods of the dependent
|
|
1400
1600
|
plugin would override the association methods created by the main
|
|
1401
1601
|
plugin.
|
|
1602
|
+
|
|
1603
|
+
==== :eager_limit_strategy
|
|
1604
|
+
|
|
1605
|
+
This setting determines what strategy to use for loading the associations
|
|
1606
|
+
that use the :limit setting to limit the number of returned records. You
|
|
1607
|
+
can't use LIMIT directly, since you want a limit for each associated
|
|
1608
|
+
record, not a LIMIT on the number of records returned by the dataset.
|
|
1609
|
+
|
|
1610
|
+
By default, no strategy is used for one_to_one associations, and
|
|
1611
|
+
the :ruby strategy is used for *_many associations, which does a simple
|
|
1612
|
+
array slice after loading the associated records. That doesn't provide
|
|
1613
|
+
a performance advantage, since all records are still loaded from the
|
|
1614
|
+
database, but it at least makes sure the cached records are accurately
|
|
1615
|
+
limited as they would be in the lazy load case.
|
|
1616
|
+
|
|
1617
|
+
The reason no strategy is used by default for one_to_one associations
|
|
1618
|
+
is that none is needed for a true one_to_one association (since there
|
|
1619
|
+
is only one associated record per current record). However, if you are
|
|
1620
|
+
using a one_to_one association where the relationship is really one_to_many,
|
|
1621
|
+
and using an order to pick the first matching row, then if you don't
|
|
1622
|
+
specify an :eager_limit_strategy option, you'll be loading all related
|
|
1623
|
+
rows just to have Sequel ignore all rows after the first. By using a
|
|
1624
|
+
strategy to change the query to only return one associated record per
|
|
1625
|
+
current record, you can get much better database performance.
|
|
1626
|
+
|
|
1627
|
+
You can set a value of +true+ for this option to have Sequel select what
|
|
1628
|
+
it thinks is the best way of limiting the records for your database. You
|
|
1629
|
+
can also specify a symbol to manually choose a strategy. The available
|
|
1630
|
+
strategies are:
|
|
1631
|
+
|
|
1632
|
+
:distinct_on :: Uses DISTINCT ON to ensure only the first matching record
|
|
1633
|
+
is loaded (one_to_one associations only). This is used by
|
|
1634
|
+
default on PostgreSQL.
|
|
1635
|
+
:window_function :: Uses window functions if the database supports it.
|
|
1636
|
+
This is used by default on databases that support window
|
|
1637
|
+
functions.
|
|
1638
|
+
:correlated_subquery :: Uses a correlated subquery to get the information.
|
|
1639
|
+
This is never used by default as if you aren't careful,
|
|
1640
|
+
it can result in pathologically long running times.
|
|
1641
|
+
This will not work correctly for associations where
|
|
1642
|
+
the associated table has a composite primary key if
|
|
1643
|
+
the database doesn't support using IN
|
|
1644
|
+
with multiple columns. This will also not work on MySQL
|
|
1645
|
+
because MySQL has problems using IN with a correlated
|
|
1646
|
+
subquery that contains a limit.
|
|
1647
|
+
:ruby :: Uses ruby array slicing to emulate database limiting (*_many
|
|
1648
|
+
associations only). This is the default if the database doesn't
|
|
1649
|
+
support window functions.
|