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
|
@@ -2,42 +2,47 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
|
2
2
|
|
|
3
3
|
describe Sequel::Model, "associate" do
|
|
4
4
|
it "should use explicit class if given a class, symbol, or string" do
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
begin
|
|
6
|
+
klass = Class.new(Sequel::Model(:nodes))
|
|
7
|
+
class ::ParParent < Sequel::Model; end
|
|
8
|
+
|
|
9
|
+
klass.associate :many_to_one, :par_parent0, :class=>ParParent
|
|
10
|
+
klass.associate :one_to_many, :par_parent1s, :class=>'ParParent'
|
|
11
|
+
klass.associate :many_to_many, :par_parent2s, :class=>:ParParent
|
|
12
|
+
|
|
13
|
+
klass.association_reflection(:"par_parent0").associated_class.should == ParParent
|
|
14
|
+
klass.association_reflection(:"par_parent1s").associated_class.should == ParParent
|
|
15
|
+
klass.association_reflection(:"par_parent2s").associated_class.should == ParParent
|
|
16
|
+
ensure
|
|
17
|
+
Object.send(:remove_const, :ParParent)
|
|
8
18
|
end
|
|
9
|
-
|
|
10
|
-
klass.associate :many_to_one, :par_parent0, :class=>ParParent
|
|
11
|
-
klass.associate :one_to_many, :par_parent1s, :class=>'ParParent'
|
|
12
|
-
klass.associate :many_to_many, :par_parent2s, :class=>:ParParent
|
|
13
|
-
|
|
14
|
-
klass.association_reflection(:"par_parent0").associated_class.should == ParParent
|
|
15
|
-
klass.association_reflection(:"par_parent1s").associated_class.should == ParParent
|
|
16
|
-
klass.association_reflection(:"par_parent2s").associated_class.should == ParParent
|
|
17
19
|
end
|
|
18
20
|
|
|
19
21
|
it "should default to associating to other models in the same scope" do
|
|
20
|
-
|
|
21
|
-
class
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
22
|
+
begin
|
|
23
|
+
class ::AssociationModuleTest
|
|
24
|
+
class Album < Sequel::Model
|
|
25
|
+
many_to_one :artist
|
|
26
|
+
many_to_many :tags
|
|
27
|
+
end
|
|
28
|
+
class Artist< Sequel::Model
|
|
29
|
+
one_to_many :albums
|
|
30
|
+
end
|
|
31
|
+
class Tag < Sequel::Model
|
|
32
|
+
many_to_many :albums
|
|
33
|
+
end
|
|
30
34
|
end
|
|
35
|
+
|
|
36
|
+
::AssociationModuleTest::Album.association_reflection(:artist).associated_class.should == ::AssociationModuleTest::Artist
|
|
37
|
+
::AssociationModuleTest::Album.association_reflection(:tags).associated_class.should == ::AssociationModuleTest::Tag
|
|
38
|
+
::AssociationModuleTest::Artist.association_reflection(:albums).associated_class.should == ::AssociationModuleTest::Album
|
|
39
|
+
::AssociationModuleTest::Tag.association_reflection(:albums).associated_class.should == ::AssociationModuleTest::Album
|
|
40
|
+
ensure
|
|
41
|
+
Object.send(:remove_const, :AssociationModuleTest)
|
|
31
42
|
end
|
|
32
|
-
|
|
33
|
-
::AssociationModuleTest::Album.association_reflection(:artist).associated_class.should == ::AssociationModuleTest::Artist
|
|
34
|
-
::AssociationModuleTest::Album.association_reflection(:tags).associated_class.should == ::AssociationModuleTest::Tag
|
|
35
|
-
::AssociationModuleTest::Artist.association_reflection(:albums).associated_class.should == ::AssociationModuleTest::Album
|
|
36
|
-
::AssociationModuleTest::Tag.association_reflection(:albums).associated_class.should == ::AssociationModuleTest::Album
|
|
37
43
|
end
|
|
38
44
|
|
|
39
45
|
it "should add a model_object and association_reflection accessors to the dataset, and return it with the current model object" do
|
|
40
|
-
MODEL_DB.reset
|
|
41
46
|
klass = Class.new(Sequel::Model(:nodes)) do
|
|
42
47
|
columns :id, :a_id
|
|
43
48
|
end
|
|
@@ -64,7 +69,6 @@ describe Sequel::Model, "associate" do
|
|
|
64
69
|
end
|
|
65
70
|
|
|
66
71
|
it "should allow extending the dataset with :extend option" do
|
|
67
|
-
MODEL_DB.reset
|
|
68
72
|
klass = Class.new(Sequel::Model(:nodes)) do
|
|
69
73
|
columns :id, :a_id
|
|
70
74
|
end
|
|
@@ -91,44 +95,58 @@ describe Sequel::Model, "associate" do
|
|
|
91
95
|
end
|
|
92
96
|
|
|
93
97
|
it "should clone an existing association with the :clone option" do
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
98
|
+
begin
|
|
99
|
+
class ::ParParent < Sequel::Model; end
|
|
100
|
+
klass = Class.new(Sequel::Model(:nodes))
|
|
101
|
+
|
|
102
|
+
klass.many_to_one(:par_parent, :order=>:a){1}
|
|
103
|
+
klass.one_to_many(:par_parent1s, :class=>'ParParent', :limit=>12){4}
|
|
104
|
+
klass.many_to_many(:par_parent2s, :class=>:ParParent, :uniq=>true){2}
|
|
100
105
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
106
|
+
klass.many_to_one :par, :clone=>:par_parent, :select=>:b
|
|
107
|
+
klass.one_to_many :par1s, :clone=>:par_parent1s, :order=>:b, :limit=>10, :block=>nil
|
|
108
|
+
klass.many_to_many(:par2s, :clone=>:par_parent2s, :order=>:c){3}
|
|
109
|
+
|
|
110
|
+
klass.association_reflection(:par).associated_class.should == ParParent
|
|
111
|
+
klass.association_reflection(:par1s).associated_class.should == ParParent
|
|
112
|
+
klass.association_reflection(:par2s).associated_class.should == ParParent
|
|
113
|
+
|
|
114
|
+
klass.association_reflection(:par)[:order].should == :a
|
|
115
|
+
klass.association_reflection(:par).select.should == :b
|
|
116
|
+
klass.association_reflection(:par)[:block].call.should == 1
|
|
117
|
+
klass.association_reflection(:par1s)[:limit].should == 10
|
|
118
|
+
klass.association_reflection(:par1s)[:order].should == :b
|
|
119
|
+
klass.association_reflection(:par1s)[:block].should == nil
|
|
120
|
+
klass.association_reflection(:par2s)[:after_load].length.should == 1
|
|
121
|
+
klass.association_reflection(:par2s)[:order].should == :c
|
|
122
|
+
klass.association_reflection(:par2s)[:block].call.should == 3
|
|
123
|
+
ensure
|
|
124
|
+
Object.send(:remove_const, :ParParent)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it "should raise an error if attempting to clone an association of differing type" do
|
|
129
|
+
c = Class.new(Sequel::Model(:c))
|
|
130
|
+
c.many_to_one :c
|
|
131
|
+
proc{c.one_to_many :cs, :clone=>:c}.should raise_error(Sequel::Error)
|
|
118
132
|
end
|
|
119
133
|
|
|
134
|
+
it "should allow cloning of one_to_many to one_to_one associations and vice-versa" do
|
|
135
|
+
c = Class.new(Sequel::Model(:c))
|
|
136
|
+
c.one_to_one :c
|
|
137
|
+
proc{c.one_to_many :cs, :clone=>:c}.should_not raise_error(Sequel::Error)
|
|
138
|
+
proc{c.one_to_one :c2, :clone=>:cs}.should_not raise_error(Sequel::Error)
|
|
139
|
+
end
|
|
120
140
|
end
|
|
121
141
|
|
|
122
142
|
describe Sequel::Model, "many_to_one" do
|
|
123
143
|
before do
|
|
124
|
-
MODEL_DB.reset
|
|
125
|
-
|
|
126
144
|
@c2 = Class.new(Sequel::Model(:nodes)) do
|
|
127
145
|
unrestrict_primary_key
|
|
128
146
|
columns :id, :parent_id, :par_parent_id, :blah
|
|
129
147
|
end
|
|
130
|
-
|
|
131
148
|
@dataset = @c2.dataset
|
|
149
|
+
MODEL_DB.reset
|
|
132
150
|
end
|
|
133
151
|
|
|
134
152
|
it "should use implicit key if omitted" do
|
|
@@ -142,32 +160,43 @@ describe Sequel::Model, "many_to_one" do
|
|
|
142
160
|
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE (nodes.id = 234) LIMIT 1"]
|
|
143
161
|
end
|
|
144
162
|
|
|
163
|
+
it "should allow association with the same name as the key if :key_alias is given" do
|
|
164
|
+
@c2.def_column_alias(:parent_id_id, :parent_id)
|
|
165
|
+
@c2.many_to_one :parent_id, :key_column=>:parent_id, :class => @c2
|
|
166
|
+
d = @c2.load(:id => 1, :parent_id => 234)
|
|
167
|
+
d.parent_id_dataset.sql.should == "SELECT * FROM nodes WHERE (nodes.id = 234) LIMIT 1"
|
|
168
|
+
d.parent_id.should == @c2.load(:x => 1, :id => 1)
|
|
169
|
+
d.parent_id_id.should == 234
|
|
170
|
+
d[:parent_id].should == 234
|
|
171
|
+
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE (nodes.id = 234) LIMIT 1"]
|
|
172
|
+
|
|
173
|
+
d.parent_id_id = 3
|
|
174
|
+
d.parent_id_id.should == 3
|
|
175
|
+
d[:parent_id].should == 3
|
|
176
|
+
end
|
|
177
|
+
|
|
145
178
|
it "should use implicit class if omitted" do
|
|
146
|
-
|
|
179
|
+
begin
|
|
180
|
+
class ::ParParent < Sequel::Model; end
|
|
181
|
+
@c2.many_to_one :par_parent
|
|
182
|
+
@c2.new(:id => 1, :par_parent_id => 234).par_parent.class.should == ParParent
|
|
183
|
+
MODEL_DB.sqls.should == ["SELECT * FROM par_parents WHERE (par_parents.id = 234) LIMIT 1"]
|
|
184
|
+
ensure
|
|
185
|
+
Object.send(:remove_const, :ParParent)
|
|
147
186
|
end
|
|
148
|
-
|
|
149
|
-
@c2.many_to_one :par_parent
|
|
150
|
-
|
|
151
|
-
d = @c2.new(:id => 1, :par_parent_id => 234)
|
|
152
|
-
p = d.par_parent
|
|
153
|
-
p.class.should == ParParent
|
|
154
|
-
|
|
155
|
-
MODEL_DB.sqls.should == ["SELECT * FROM par_parents WHERE (par_parents.id = 234) LIMIT 1"]
|
|
156
187
|
end
|
|
157
188
|
|
|
158
189
|
it "should use class inside module if given as a string" do
|
|
159
|
-
|
|
160
|
-
|
|
190
|
+
begin
|
|
191
|
+
module ::Par
|
|
192
|
+
class Parent < Sequel::Model; end
|
|
161
193
|
end
|
|
194
|
+
@c2.many_to_one :par_parent, :class=>"Par::Parent"
|
|
195
|
+
@c2.new(:id => 1, :par_parent_id => 234).par_parent.class.should == Par::Parent
|
|
196
|
+
MODEL_DB.sqls.should == ["SELECT * FROM parents WHERE (parents.id = 234) LIMIT 1"]
|
|
197
|
+
ensure
|
|
198
|
+
Object.send(:remove_const, :Par)
|
|
162
199
|
end
|
|
163
|
-
|
|
164
|
-
@c2.many_to_one :par_parent, :class=>"Par::Parent"
|
|
165
|
-
|
|
166
|
-
d = @c2.new(:id => 1, :par_parent_id => 234)
|
|
167
|
-
p = d.par_parent
|
|
168
|
-
p.class.should == Par::Parent
|
|
169
|
-
|
|
170
|
-
MODEL_DB.sqls.should == ["SELECT * FROM parents WHERE (parents.id = 234) LIMIT 1"]
|
|
171
200
|
end
|
|
172
201
|
|
|
173
202
|
it "should use explicit key if given" do
|
|
@@ -181,6 +210,12 @@ describe Sequel::Model, "many_to_one" do
|
|
|
181
210
|
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE (nodes.id = 567) LIMIT 1"]
|
|
182
211
|
end
|
|
183
212
|
|
|
213
|
+
it "should respect :qualify => false option" do
|
|
214
|
+
@c2.many_to_one :parent, :class => @c2, :key => :blah, :qualify=>false
|
|
215
|
+
@c2.new(:id => 1, :blah => 567).parent
|
|
216
|
+
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE (id = 567) LIMIT 1"]
|
|
217
|
+
end
|
|
218
|
+
|
|
184
219
|
it "should use :primary_key option if given" do
|
|
185
220
|
@c2.many_to_one :parent, :class => @c2, :key => :blah, :primary_key => :pk
|
|
186
221
|
@c2.new(:id => 1, :blah => 567).parent
|
|
@@ -218,15 +253,13 @@ describe Sequel::Model, "many_to_one" do
|
|
|
218
253
|
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE ((nodes.id = 567) AND (a = 32)) LIMIT 1"]
|
|
219
254
|
|
|
220
255
|
@c2.many_to_one :parent, :class => @c2, :key => :blah, :conditions=>:a
|
|
221
|
-
MODEL_DB.sqls.clear
|
|
222
256
|
@c2.new(:id => 1, :blah => 567).parent
|
|
223
257
|
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE ((nodes.id = 567) AND a) LIMIT 1"]
|
|
224
258
|
end
|
|
225
259
|
|
|
226
260
|
it "should support :order, :limit (only for offset), and :dataset options, as well as a block" do
|
|
227
|
-
c2
|
|
228
|
-
|
|
229
|
-
ds.filter(:x.sql_number > 1)
|
|
261
|
+
@c2.many_to_one :child_20, :class => @c2, :key=>:id, :dataset=>proc{model.filter(:parent_id=>pk)}, :limit=>[10,20], :order=>:name do |ds|
|
|
262
|
+
ds.filter{x > 1}
|
|
230
263
|
end
|
|
231
264
|
@c2.load(:id => 100).child_20
|
|
232
265
|
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE ((parent_id = 100) AND (x > 1)) ORDER BY name LIMIT 1 OFFSET 20"]
|
|
@@ -234,24 +267,19 @@ describe Sequel::Model, "many_to_one" do
|
|
|
234
267
|
|
|
235
268
|
it "should return nil if key value is nil" do
|
|
236
269
|
@c2.many_to_one :parent, :class => @c2
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
d.parent.should == nil
|
|
270
|
+
@c2.new(:id => 1).parent.should == nil
|
|
271
|
+
MODEL_DB.sqls.should == []
|
|
240
272
|
end
|
|
241
273
|
|
|
242
274
|
it "should cache negative lookup" do
|
|
243
275
|
@c2.many_to_one :parent, :class => @c2
|
|
244
|
-
|
|
245
|
-
def ds.fetch_rows(sql, &block)
|
|
246
|
-
MODEL_DB.sqls << sql
|
|
247
|
-
end
|
|
248
|
-
|
|
276
|
+
@c2.dataset._fetch = []
|
|
249
277
|
d = @c2.new(:id => 1, :parent_id=>555)
|
|
250
278
|
MODEL_DB.sqls.should == []
|
|
251
279
|
d.parent.should == nil
|
|
252
280
|
MODEL_DB.sqls.should == ['SELECT * FROM nodes WHERE (nodes.id = 555) LIMIT 1']
|
|
253
281
|
d.parent.should == nil
|
|
254
|
-
MODEL_DB.sqls.should == [
|
|
282
|
+
MODEL_DB.sqls.should == []
|
|
255
283
|
end
|
|
256
284
|
|
|
257
285
|
it "should define a setter method" do
|
|
@@ -314,11 +342,9 @@ describe Sequel::Model, "many_to_one" do
|
|
|
314
342
|
@c2.many_to_one :parent, :class => @c2
|
|
315
343
|
|
|
316
344
|
d = @c2.load(:id => 1)
|
|
317
|
-
MODEL_DB.reset
|
|
318
345
|
d.parent_id = 234
|
|
319
346
|
d.associations[:parent].should == nil
|
|
320
|
-
|
|
321
|
-
def ds.fetch_rows(sql, &block); MODEL_DB.sqls << sql; yield({:id=>234}) end
|
|
347
|
+
@c2.dataset._fetch = {:id=>234}
|
|
322
348
|
e = d.parent
|
|
323
349
|
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE (nodes.id = 234) LIMIT 1"]
|
|
324
350
|
d.associations[:parent].should == e
|
|
@@ -357,13 +383,32 @@ describe Sequel::Model, "many_to_one" do
|
|
|
357
383
|
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE (nodes.id = 234) LIMIT 1"]
|
|
358
384
|
end
|
|
359
385
|
|
|
386
|
+
it "should use a callback if given one as the argument" do
|
|
387
|
+
@c2.many_to_one :parent, :class => @c2
|
|
388
|
+
|
|
389
|
+
d = @c2.create(:id => 1)
|
|
390
|
+
MODEL_DB.reset
|
|
391
|
+
d.parent_id = 234
|
|
392
|
+
d.associations[:parent] = 42
|
|
393
|
+
d.parent(proc{|ds| ds.filter{name > 'M'}}).should_not == 42
|
|
394
|
+
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE ((nodes.id = 234) AND (name > 'M')) LIMIT 1"]
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
it "should use a block given to the association method as a callback" do
|
|
398
|
+
@c2.many_to_one :parent, :class => @c2
|
|
399
|
+
|
|
400
|
+
d = @c2.create(:id => 1)
|
|
401
|
+
MODEL_DB.reset
|
|
402
|
+
d.parent_id = 234
|
|
403
|
+
d.associations[:parent] = 42
|
|
404
|
+
d.parent{|ds| ds.filter{name > 'M'}}.should_not == 42
|
|
405
|
+
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE ((nodes.id = 234) AND (name > 'M')) LIMIT 1"]
|
|
406
|
+
end
|
|
407
|
+
|
|
360
408
|
it "should have the setter add to the reciprocal one_to_many cached association list if it exists" do
|
|
361
409
|
@c2.many_to_one :parent, :class => @c2
|
|
362
410
|
@c2.one_to_many :children, :class => @c2, :key=>:parent_id
|
|
363
|
-
|
|
364
|
-
def ds.fetch_rows(sql, &block)
|
|
365
|
-
MODEL_DB.sqls << sql
|
|
366
|
-
end
|
|
411
|
+
@c2.dataset._fetch = []
|
|
367
412
|
|
|
368
413
|
d = @c2.new(:id => 1)
|
|
369
414
|
e = @c2.new(:id => 2)
|
|
@@ -372,14 +417,13 @@ describe Sequel::Model, "many_to_one" do
|
|
|
372
417
|
e.children.should_not(include(d))
|
|
373
418
|
MODEL_DB.sqls.should == ['SELECT * FROM nodes WHERE (nodes.parent_id = 2)']
|
|
374
419
|
|
|
375
|
-
MODEL_DB.reset
|
|
376
420
|
d = @c2.new(:id => 1)
|
|
377
421
|
e = @c2.new(:id => 2)
|
|
378
422
|
e.children.should_not(include(d))
|
|
379
423
|
MODEL_DB.sqls.should == ['SELECT * FROM nodes WHERE (nodes.parent_id = 2)']
|
|
380
424
|
d.parent = e
|
|
381
425
|
e.children.should(include(d))
|
|
382
|
-
MODEL_DB.sqls.should == [
|
|
426
|
+
MODEL_DB.sqls.should == []
|
|
383
427
|
end
|
|
384
428
|
|
|
385
429
|
it "should have many_to_one setter deal with a one_to_one reciprocal" do
|
|
@@ -407,10 +451,7 @@ describe Sequel::Model, "many_to_one" do
|
|
|
407
451
|
it "should have the setter remove the object from the previous associated object's reciprocal one_to_many cached association list if it exists" do
|
|
408
452
|
@c2.many_to_one :parent, :class => @c2
|
|
409
453
|
@c2.one_to_many :children, :class => @c2, :key=>:parent_id
|
|
410
|
-
|
|
411
|
-
def ds.fetch_rows(sql, &block)
|
|
412
|
-
MODEL_DB.sqls << sql
|
|
413
|
-
end
|
|
454
|
+
@c2.dataset._fetch = []
|
|
414
455
|
|
|
415
456
|
d = @c2.new(:id => 1)
|
|
416
457
|
e = @c2.new(:id => 2)
|
|
@@ -428,18 +469,24 @@ describe Sequel::Model, "many_to_one" do
|
|
|
428
469
|
MODEL_DB.sqls.should == []
|
|
429
470
|
end
|
|
430
471
|
|
|
472
|
+
it "should have the setter not modify the reciprocal if set to same value as current" do
|
|
473
|
+
@c2.many_to_one :parent, :class => @c2
|
|
474
|
+
@c2.one_to_many :children, :class => @c2, :key=>:parent_id
|
|
475
|
+
|
|
476
|
+
c1 = @c2.load(:id => 1, :parent_id=>nil)
|
|
477
|
+
c2 = @c2.load(:id => 2, :parent_id=>1)
|
|
478
|
+
c3 = @c2.load(:id => 3, :parent_id=>1)
|
|
479
|
+
c1.associations[:children] = [c2, c3]
|
|
480
|
+
c2.associations[:parent] = c1
|
|
481
|
+
c2.parent = c1
|
|
482
|
+
c1.children.should == [c2, c3]
|
|
483
|
+
MODEL_DB.sqls.should == []
|
|
484
|
+
end
|
|
485
|
+
|
|
431
486
|
it "should get all matching records and only return the first if :key option is set to nil" do
|
|
432
|
-
c2 = @c2
|
|
433
487
|
@c2.one_to_many :children, :class => @c2, :key=>:parent_id
|
|
434
|
-
@c2.many_to_one :first_grand_parent, :class => @c2, :key=>nil, :eager_graph=>:children, :dataset=>proc{
|
|
435
|
-
|
|
436
|
-
def ds.columns
|
|
437
|
-
[:id, :parent_id, :par_parent_id, :blah]
|
|
438
|
-
end
|
|
439
|
-
def ds.fetch_rows(sql, &block)
|
|
440
|
-
MODEL_DB.sqls << sql
|
|
441
|
-
yield({:id=>1, :parent_id=>0, :par_parent_id=>3, :blah=>4, :children_id=>2, :children_parent_id=>1, :children_par_parent_id=>5, :children_blah=>6})
|
|
442
|
-
end
|
|
488
|
+
@c2.many_to_one :first_grand_parent, :class => @c2, :key=>nil, :eager_graph=>:children, :dataset=>proc{model.filter(:children_id=>parent_id)}
|
|
489
|
+
@c2.dataset.columns(:id, :parent_id, :par_parent_id, :blah)._fetch = [{:id=>1, :parent_id=>0, :par_parent_id=>3, :blah=>4, :children_id=>2, :children_parent_id=>1, :children_par_parent_id=>5, :children_blah=>6}, {}]
|
|
443
490
|
p = @c2.new(:parent_id=>2)
|
|
444
491
|
fgp = p.first_grand_parent
|
|
445
492
|
MODEL_DB.sqls.should == ["SELECT nodes.id, nodes.parent_id, nodes.par_parent_id, nodes.blah, children.id AS children_id, children.parent_id AS children_parent_id, children.par_parent_id AS children_par_parent_id, children.blah AS children_blah FROM nodes LEFT OUTER JOIN nodes AS children ON (children.parent_id = nodes.id) WHERE (children_id = 2)"]
|
|
@@ -500,15 +547,15 @@ describe Sequel::Model, "many_to_one" do
|
|
|
500
547
|
h = []
|
|
501
548
|
@c2.many_to_one :parent, :class => @c2, :before_set=>[proc{|x,y| h << x.pk; h << (y ? -y.pk : :y)}, :blah], :after_set=>proc{h << 3}
|
|
502
549
|
@c2.class_eval do
|
|
503
|
-
|
|
550
|
+
self::Foo = h
|
|
504
551
|
def []=(a, v)
|
|
505
|
-
a == :parent_id ? (
|
|
552
|
+
a == :parent_id ? (model::Foo << (v ? 4 : 5)) : super
|
|
506
553
|
end
|
|
507
554
|
def blah(x)
|
|
508
|
-
|
|
555
|
+
model::Foo << (x ? x.pk : :x)
|
|
509
556
|
end
|
|
510
557
|
def blahr(x)
|
|
511
|
-
|
|
558
|
+
model::Foo << 6
|
|
512
559
|
end
|
|
513
560
|
end
|
|
514
561
|
p = @c2.load(:id=>10)
|
|
@@ -524,13 +571,11 @@ describe Sequel::Model, "many_to_one" do
|
|
|
524
571
|
h = []
|
|
525
572
|
@c2.many_to_one :parent, :class => @c2, :after_load=>[proc{|x,y| h << [x.pk, y.pk]}, :al]
|
|
526
573
|
@c2.class_eval do
|
|
527
|
-
|
|
574
|
+
self::Foo = h
|
|
528
575
|
def al(v)
|
|
529
|
-
|
|
530
|
-
end
|
|
531
|
-
def @dataset.fetch_rows(sql)
|
|
532
|
-
yield({:id=>20})
|
|
576
|
+
model::Foo << v.pk
|
|
533
577
|
end
|
|
578
|
+
dataset._fetch = {:id=>20}
|
|
534
579
|
end
|
|
535
580
|
p = @c2.load(:id=>10, :parent_id=>20)
|
|
536
581
|
parent = p.parent
|
|
@@ -538,6 +583,18 @@ describe Sequel::Model, "many_to_one" do
|
|
|
538
583
|
parent.pk.should == 20
|
|
539
584
|
end
|
|
540
585
|
|
|
586
|
+
it "should support after_load association callback that changes the cached object" do
|
|
587
|
+
@c2.many_to_one :parent, :class => @c2, :after_load=>:al
|
|
588
|
+
@c2.class_eval do
|
|
589
|
+
def al(v)
|
|
590
|
+
associations[:parent] = :foo
|
|
591
|
+
end
|
|
592
|
+
end
|
|
593
|
+
p = @c2.load(:id=>10, :parent_id=>20)
|
|
594
|
+
p.parent.should == :foo
|
|
595
|
+
p.associations[:parent].should == :foo
|
|
596
|
+
end
|
|
597
|
+
|
|
541
598
|
it "should raise error and not call internal add or remove method if before callback returns false, even if raise_on_save_failure is false" do
|
|
542
599
|
# The reason for this is that assignment in ruby always returns the argument instead of the result
|
|
543
600
|
# of the method, so we can't return nil to signal that the association callback prevented the modification
|
|
@@ -565,35 +622,32 @@ describe Sequel::Model, "many_to_one" do
|
|
|
565
622
|
d = @c2.load(:id=>321)
|
|
566
623
|
p = @c2.new
|
|
567
624
|
p.associations[:parent] = d
|
|
568
|
-
h = []
|
|
569
625
|
@c2.many_to_one :parent, :class => @c2, :before_set=>:bs, :after_set=>:as
|
|
570
626
|
@c2.class_eval do
|
|
571
|
-
|
|
627
|
+
self::Foo = []
|
|
572
628
|
def []=(a, v)
|
|
573
|
-
a == :parent_id ? (
|
|
629
|
+
a == :parent_id ? (model::Foo << 5) : super
|
|
574
630
|
end
|
|
575
631
|
def bs(x)
|
|
576
|
-
|
|
632
|
+
model::Foo << x.pk
|
|
577
633
|
end
|
|
578
634
|
def as(x)
|
|
579
|
-
|
|
635
|
+
model::Foo << x.pk * 2
|
|
580
636
|
end
|
|
581
637
|
end
|
|
582
638
|
p.parent = c
|
|
583
|
-
|
|
639
|
+
@c2::Foo.should == [123, 5, 246]
|
|
584
640
|
end
|
|
585
641
|
end
|
|
586
642
|
|
|
587
643
|
describe Sequel::Model, "one_to_one" do
|
|
588
644
|
before do
|
|
589
645
|
@c1 = Class.new(Sequel::Model(:attributes)) do
|
|
590
|
-
def _refresh(ds); end
|
|
591
646
|
unrestrict_primary_key
|
|
592
647
|
columns :id, :node_id, :y
|
|
593
648
|
end
|
|
594
649
|
|
|
595
650
|
@c2 = Class.new(Sequel::Model(:nodes)) do
|
|
596
|
-
def _refresh(ds); end
|
|
597
651
|
unrestrict_primary_key
|
|
598
652
|
attr_accessor :xxx
|
|
599
653
|
|
|
@@ -602,24 +656,8 @@ describe Sequel::Model, "one_to_one" do
|
|
|
602
656
|
columns :id, :x, :parent_id, :par_parent_id, :blah, :node_id
|
|
603
657
|
end
|
|
604
658
|
@dataset = @c2.dataset
|
|
605
|
-
|
|
606
|
-
@
|
|
607
|
-
def empty?; false; end
|
|
608
|
-
def fetch_rows(sql)
|
|
609
|
-
@db << sql
|
|
610
|
-
yield Hash.new
|
|
611
|
-
end
|
|
612
|
-
})
|
|
613
|
-
|
|
614
|
-
@c1.dataset.extend(Module.new {
|
|
615
|
-
def empty?; opts.has_key?(:empty) ? (super; true) : false; end
|
|
616
|
-
def fetch_rows(sql)
|
|
617
|
-
@db << sql
|
|
618
|
-
yield Hash.new
|
|
619
|
-
end
|
|
620
|
-
})
|
|
621
|
-
|
|
622
|
-
@dataset = @c2.dataset
|
|
659
|
+
@dataset._fetch = {}
|
|
660
|
+
@c1.dataset._fetch = {}
|
|
623
661
|
MODEL_DB.reset
|
|
624
662
|
end
|
|
625
663
|
|
|
@@ -641,26 +679,24 @@ describe Sequel::Model, "one_to_one" do
|
|
|
641
679
|
it "should add a setter method" do
|
|
642
680
|
@c2.one_to_one :attribute, :class => @c1
|
|
643
681
|
attrib = @c1.new(:id=>3)
|
|
644
|
-
|
|
645
|
-
@c1.class_eval{remove_method :_refresh}
|
|
646
|
-
def d.fetch_rows(s); yield({:id=>3}) end
|
|
682
|
+
@c1.dataset._fetch = @c1.instance_dataset._fetch = {:id=>3}
|
|
647
683
|
@c2.new(:id => 1234).attribute = attrib
|
|
684
|
+
sqls = MODEL_DB.sqls
|
|
648
685
|
['INSERT INTO attributes (node_id, id) VALUES (1234, 3)',
|
|
649
|
-
'INSERT INTO attributes (id, node_id) VALUES (3, 1234)'].should(include(
|
|
650
|
-
|
|
651
|
-
|
|
686
|
+
'INSERT INTO attributes (id, node_id) VALUES (3, 1234)'].should(include(sqls.slice! 1))
|
|
687
|
+
sqls.should == ['UPDATE attributes SET node_id = NULL WHERE (node_id = 1234)', "SELECT * FROM attributes WHERE (id = 3) LIMIT 1"]
|
|
688
|
+
|
|
652
689
|
@c2.new(:id => 1234).attribute.should == attrib
|
|
653
|
-
MODEL_DB.sqls.clear
|
|
654
690
|
attrib = @c1.load(:id=>3)
|
|
655
691
|
@c2.new(:id => 1234).attribute = attrib
|
|
656
|
-
MODEL_DB.sqls.should == [
|
|
692
|
+
MODEL_DB.sqls.should == ["SELECT * FROM attributes WHERE (attributes.node_id = 1234) LIMIT 1",
|
|
693
|
+
'UPDATE attributes SET node_id = NULL WHERE ((node_id = 1234) AND (id != 3))',
|
|
657
694
|
"UPDATE attributes SET node_id = 1234 WHERE (id = 3)"]
|
|
658
695
|
end
|
|
659
696
|
|
|
660
697
|
it "should use a transaction in the setter method" do
|
|
661
698
|
@c2.one_to_one :attribute, :class => @c1
|
|
662
699
|
@c2.use_transactions = true
|
|
663
|
-
MODEL_DB.sqls.clear
|
|
664
700
|
attrib = @c1.load(:id=>3)
|
|
665
701
|
@c2.new(:id => 1234).attribute = attrib
|
|
666
702
|
MODEL_DB.sqls.should == ['BEGIN',
|
|
@@ -673,7 +709,6 @@ describe Sequel::Model, "one_to_one" do
|
|
|
673
709
|
@c2.one_to_one :attribute, :class => @c1, :conditions=>{:a=>1} do |ds|
|
|
674
710
|
ds.filter(:b=>2)
|
|
675
711
|
end
|
|
676
|
-
MODEL_DB.sqls.clear
|
|
677
712
|
attrib = @c1.load(:id=>3)
|
|
678
713
|
@c2.new(:id => 1234).attribute = attrib
|
|
679
714
|
MODEL_DB.sqls.should == ['UPDATE attributes SET node_id = NULL WHERE ((node_id = 1234) AND (a = 1) AND (b = 2) AND (id != 3))',
|
|
@@ -683,30 +718,30 @@ describe Sequel::Model, "one_to_one" do
|
|
|
683
718
|
it "should have the setter method respect the :primary_key option" do
|
|
684
719
|
@c2.one_to_one :attribute, :class => @c1, :primary_key=>:xxx
|
|
685
720
|
attrib = @c1.new(:id=>3)
|
|
686
|
-
|
|
687
|
-
@c1.class_eval{remove_method :_refresh}
|
|
688
|
-
def d.fetch_rows(s); yield({:id=>3}) end
|
|
721
|
+
@c1.dataset._fetch = @c1.instance_dataset._fetch = {:id=>3}
|
|
689
722
|
@c2.new(:id => 1234, :xxx=>5).attribute = attrib
|
|
723
|
+
sqls = MODEL_DB.sqls
|
|
690
724
|
['INSERT INTO attributes (node_id, id) VALUES (5, 3)',
|
|
691
|
-
'INSERT INTO attributes (id, node_id) VALUES (3, 5)'].should(include(
|
|
692
|
-
|
|
693
|
-
|
|
725
|
+
'INSERT INTO attributes (id, node_id) VALUES (3, 5)'].should(include(sqls.slice! 1))
|
|
726
|
+
sqls.should == ['UPDATE attributes SET node_id = NULL WHERE (node_id = 5)', "SELECT * FROM attributes WHERE (id = 3) LIMIT 1"]
|
|
727
|
+
|
|
694
728
|
@c2.new(:id => 321, :xxx=>5).attribute.should == attrib
|
|
695
|
-
MODEL_DB.sqls.clear
|
|
696
729
|
attrib = @c1.load(:id=>3)
|
|
697
730
|
@c2.new(:id => 621, :xxx=>5).attribute = attrib
|
|
698
|
-
MODEL_DB.sqls.should == [
|
|
731
|
+
MODEL_DB.sqls.should == ["SELECT * FROM attributes WHERE (attributes.node_id = 5) LIMIT 1",
|
|
732
|
+
'UPDATE attributes SET node_id = NULL WHERE ((node_id = 5) AND (id != 3))',
|
|
699
733
|
'UPDATE attributes SET node_id = 5 WHERE (id = 3)']
|
|
700
734
|
end
|
|
701
735
|
|
|
702
736
|
it "should have the setter method respect composite keys" do
|
|
703
737
|
@c2.one_to_one :attribute, :class => @c1, :key=>[:node_id, :y], :primary_key=>[:id, :x]
|
|
704
738
|
attrib = @c1.load(:id=>3, :y=>6)
|
|
705
|
-
|
|
706
|
-
def d.fetch_rows(s); yield({:id=>3, :y=>6}) end
|
|
739
|
+
@c1.dataset._fetch = {:id=>3, :y=>6}
|
|
707
740
|
@c2.load(:id => 1234, :x=>5).attribute = attrib
|
|
708
|
-
|
|
709
|
-
|
|
741
|
+
sqls = MODEL_DB.sqls
|
|
742
|
+
sqls.last.should =~ /UPDATE attributes SET (node_id = 1234|y = 5), (node_id = 1234|y = 5) WHERE \(id = 3\)/
|
|
743
|
+
sqls.first.should =~ /UPDATE attributes SET (node_id|y) = NULL, (node_id|y) = NULL WHERE \(\(node_id = 1234\) AND \(y = 5\) AND \(id != 3\)\)/
|
|
744
|
+
sqls.length.should == 2
|
|
710
745
|
end
|
|
711
746
|
|
|
712
747
|
it "should use implicit key if omitted" do
|
|
@@ -721,31 +756,27 @@ describe Sequel::Model, "one_to_one" do
|
|
|
721
756
|
end
|
|
722
757
|
|
|
723
758
|
it "should use implicit class if omitted" do
|
|
724
|
-
|
|
759
|
+
begin
|
|
760
|
+
class ::ParParent < Sequel::Model; end
|
|
761
|
+
@c2.one_to_one :par_parent
|
|
762
|
+
@c2.new(:id => 234).par_parent.class.should == ParParent
|
|
763
|
+
MODEL_DB.sqls.should == ["SELECT * FROM par_parents WHERE (par_parents.node_id = 234) LIMIT 1"]
|
|
764
|
+
ensure
|
|
765
|
+
Object.send(:remove_const, :ParParent)
|
|
725
766
|
end
|
|
726
|
-
|
|
727
|
-
@c2.one_to_one :par_parent
|
|
728
|
-
|
|
729
|
-
d = @c2.new(:id => 234)
|
|
730
|
-
p = d.par_parent
|
|
731
|
-
p.class.should == ParParent
|
|
732
|
-
|
|
733
|
-
MODEL_DB.sqls.should == ["SELECT * FROM par_parents WHERE (par_parents.node_id = 234) LIMIT 1"]
|
|
734
767
|
end
|
|
735
768
|
|
|
736
769
|
it "should use class inside module if given as a string" do
|
|
737
|
-
|
|
738
|
-
|
|
770
|
+
begin
|
|
771
|
+
module ::Par
|
|
772
|
+
class Parent < Sequel::Model; end
|
|
739
773
|
end
|
|
774
|
+
@c2.one_to_one :par_parent, :class=>"Par::Parent"
|
|
775
|
+
@c2.new(:id => 234).par_parent.class.should == Par::Parent
|
|
776
|
+
MODEL_DB.sqls.should == ["SELECT * FROM parents WHERE (parents.node_id = 234) LIMIT 1"]
|
|
777
|
+
ensure
|
|
778
|
+
Object.send(:remove_const, :Par)
|
|
740
779
|
end
|
|
741
|
-
|
|
742
|
-
@c2.one_to_one :par_parent, :class=>"Par::Parent"
|
|
743
|
-
|
|
744
|
-
d = @c2.new(:id => 234)
|
|
745
|
-
p = d.par_parent
|
|
746
|
-
p.class.should == Par::Parent
|
|
747
|
-
|
|
748
|
-
MODEL_DB.sqls.should == ["SELECT * FROM parents WHERE (parents.node_id = 234) LIMIT 1"]
|
|
749
780
|
end
|
|
750
781
|
|
|
751
782
|
it "should use explicit key if given" do
|
|
@@ -796,15 +827,13 @@ describe Sequel::Model, "one_to_one" do
|
|
|
796
827
|
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE ((nodes.node_id = 567) AND (a = 32)) LIMIT 1"]
|
|
797
828
|
|
|
798
829
|
@c2.one_to_one :parent, :class => @c2, :conditions=>:a
|
|
799
|
-
MODEL_DB.sqls.clear
|
|
800
830
|
@c2.new(:id => 567).parent
|
|
801
831
|
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE ((nodes.node_id = 567) AND a) LIMIT 1"]
|
|
802
832
|
end
|
|
803
833
|
|
|
804
834
|
it "should support :order, :limit (only for offset), and :dataset options, as well as a block" do
|
|
805
|
-
c2
|
|
806
|
-
|
|
807
|
-
ds.filter(:x.sql_number > 1)
|
|
835
|
+
@c2.one_to_one :child_20, :class => @c2, :key=>:id, :dataset=>proc{model.filter(:parent_id=>pk)}, :limit=>[10,20], :order=>:name do |ds|
|
|
836
|
+
ds.filter{x > 1}
|
|
808
837
|
end
|
|
809
838
|
@c2.load(:id => 100).child_20
|
|
810
839
|
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE ((parent_id = 100) AND (x > 1)) ORDER BY name LIMIT 1 OFFSET 20"]
|
|
@@ -813,53 +842,32 @@ describe Sequel::Model, "one_to_one" do
|
|
|
813
842
|
it "should return nil if primary_key value is nil" do
|
|
814
843
|
@c2.one_to_one :parent, :class => @c2, :primary_key=>:node_id
|
|
815
844
|
|
|
816
|
-
|
|
817
|
-
d.parent.should == nil
|
|
845
|
+
@c2.new(:id => 1).parent.should be_nil
|
|
818
846
|
MODEL_DB.sqls.should == []
|
|
819
847
|
end
|
|
820
848
|
|
|
821
849
|
it "should cache negative lookup" do
|
|
822
850
|
@c2.one_to_one :parent, :class => @c2
|
|
823
|
-
|
|
824
|
-
def ds.fetch_rows(sql, &block)
|
|
825
|
-
MODEL_DB.sqls << sql
|
|
826
|
-
end
|
|
827
|
-
|
|
851
|
+
@c2.dataset._fetch = []
|
|
828
852
|
d = @c2.new(:id => 555)
|
|
829
853
|
MODEL_DB.sqls.should == []
|
|
830
854
|
d.parent.should == nil
|
|
831
855
|
MODEL_DB.sqls.should == ['SELECT * FROM nodes WHERE (nodes.node_id = 555) LIMIT 1']
|
|
832
856
|
d.parent.should == nil
|
|
833
|
-
MODEL_DB.sqls.should == [
|
|
857
|
+
MODEL_DB.sqls.should == []
|
|
834
858
|
end
|
|
835
859
|
|
|
836
|
-
it "should define a setter method" do
|
|
837
|
-
@c2.one_to_one :parent, :class => @c2
|
|
838
|
-
|
|
839
|
-
d = @c2.new(:id => 1)
|
|
840
|
-
f = @c2.new(:id => 3, :node_id=> 4321)
|
|
841
|
-
d.parent = f
|
|
842
|
-
f.values.should == {:id => 3, :node_id=>1}
|
|
843
|
-
d.parent.should == f
|
|
844
|
-
|
|
845
|
-
d.parent = nil
|
|
846
|
-
d.parent.should == nil
|
|
847
|
-
end
|
|
848
|
-
|
|
849
|
-
it "should have the setter method respect the :primary_key option" do
|
|
850
|
-
@c2.one_to_one :parent, :class => @c2, :primary_key=>:blah
|
|
851
|
-
d = @c2.new(:id => 1, :blah => 3)
|
|
852
|
-
e = @c2.new(:id => 4321, :node_id=>444)
|
|
853
|
-
d.parent = e
|
|
854
|
-
e.values.should == {:id => 4321, :node_id => 3}
|
|
855
|
-
end
|
|
856
|
-
|
|
857
860
|
it "should have the setter method respect the :key option" do
|
|
858
861
|
@c2.one_to_one :parent, :class => @c2, :key=>:blah
|
|
859
862
|
d = @c2.new(:id => 3)
|
|
860
863
|
e = @c2.new(:id => 4321, :blah=>444)
|
|
864
|
+
@c2.dataset._fetch = @c2.instance_dataset._fetch = {:id => 4321, :blah => 3}
|
|
861
865
|
d.parent = e
|
|
862
866
|
e.values.should == {:id => 4321, :blah => 3}
|
|
867
|
+
sqls = MODEL_DB.sqls
|
|
868
|
+
["INSERT INTO nodes (blah, id) VALUES (3, 4321)",
|
|
869
|
+
"INSERT INTO nodes (id, blah) VALUES (4321, 3)"].should include(sqls.slice! 1)
|
|
870
|
+
sqls.should == ["UPDATE nodes SET blah = NULL WHERE (blah = 3)", "SELECT * FROM nodes WHERE (id = 4321) LIMIT 1"]
|
|
863
871
|
end
|
|
864
872
|
|
|
865
873
|
it "should persist changes to associated object when the setter is called" do
|
|
@@ -875,12 +883,11 @@ describe Sequel::Model, "one_to_one" do
|
|
|
875
883
|
|
|
876
884
|
d = @c2.load(:id => 1)
|
|
877
885
|
d.associations[:parent].should == nil
|
|
878
|
-
|
|
879
|
-
def ds.fetch_rows(sql, &block); MODEL_DB.sqls << sql; yield({:id=>234}) end
|
|
886
|
+
@c2.dataset._fetch = {:id=>234}
|
|
880
887
|
e = d.parent
|
|
881
888
|
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE (nodes.node_id = 1) LIMIT 1"]
|
|
882
889
|
d.parent
|
|
883
|
-
MODEL_DB.sqls.should == [
|
|
890
|
+
MODEL_DB.sqls.should == []
|
|
884
891
|
d.associations[:parent].should == e
|
|
885
892
|
end
|
|
886
893
|
|
|
@@ -922,7 +929,6 @@ describe Sequel::Model, "one_to_one" do
|
|
|
922
929
|
e.child.should == d
|
|
923
930
|
MODEL_DB.sqls.should == ["UPDATE nodes SET parent_id = NULL WHERE ((parent_id = 1) AND (id != 2))",
|
|
924
931
|
"UPDATE nodes SET parent_id = 1 WHERE (id = 2)"]
|
|
925
|
-
MODEL_DB.reset
|
|
926
932
|
d.parent = nil
|
|
927
933
|
e.child.should == nil
|
|
928
934
|
MODEL_DB.sqls.should == ["UPDATE nodes SET parent_id = NULL WHERE (parent_id = 1)"]
|
|
@@ -931,17 +937,13 @@ describe Sequel::Model, "one_to_one" do
|
|
|
931
937
|
it "should have the setter remove the object from the previous associated object's reciprocal many_to_one cached association list if it exists" do
|
|
932
938
|
@c2.one_to_one :parent, :class => @c2, :key=>:parent_id
|
|
933
939
|
@c2.many_to_one :child, :class => @c2, :key=>:parent_id
|
|
934
|
-
|
|
935
|
-
def ds.fetch_rows(sql, &block)
|
|
936
|
-
MODEL_DB.sqls << sql
|
|
937
|
-
end
|
|
940
|
+
@c2.dataset._fetch = []
|
|
938
941
|
|
|
939
942
|
d = @c2.load(:id => 1)
|
|
940
943
|
e = @c2.load(:id => 2)
|
|
941
944
|
f = @c2.load(:id => 3)
|
|
942
945
|
e.child.should == nil
|
|
943
946
|
f.child.should == nil
|
|
944
|
-
MODEL_DB.reset
|
|
945
947
|
d.parent = e
|
|
946
948
|
e.child.should == d
|
|
947
949
|
d.parent = f
|
|
@@ -951,6 +953,19 @@ describe Sequel::Model, "one_to_one" do
|
|
|
951
953
|
f.child.should == nil
|
|
952
954
|
end
|
|
953
955
|
|
|
956
|
+
it "should have the setter not modify the reciprocal if set to same value as current" do
|
|
957
|
+
@c2.one_to_one :parent, :class => @c2, :key=>:parent_id
|
|
958
|
+
@c2.many_to_one :child, :class => @c2, :key=>:parent_id
|
|
959
|
+
|
|
960
|
+
c1 = @c2.load(:id => 1, :parent_id=>nil)
|
|
961
|
+
c2 = @c2.load(:id => 2, :parent_id=>1)
|
|
962
|
+
c1.associations[:child] = c2
|
|
963
|
+
c2.associations[:parent] = c1
|
|
964
|
+
c2.parent = c1
|
|
965
|
+
c1.child.should == c2
|
|
966
|
+
MODEL_DB.sqls.should == []
|
|
967
|
+
end
|
|
968
|
+
|
|
954
969
|
it "should not add associations methods directly to class" do
|
|
955
970
|
@c2.one_to_one :parent, :class => @c2
|
|
956
971
|
@c2.instance_methods.collect{|x| x.to_s}.should(include('parent'))
|
|
@@ -983,12 +998,12 @@ describe Sequel::Model, "one_to_one" do
|
|
|
983
998
|
h = []
|
|
984
999
|
@c2.one_to_one :parent, :class => @c2, :before_set=>[proc{|x,y| h << x.pk; h << (y ? -y.pk : :y)}, :blah], :after_set=>proc{h << 3}
|
|
985
1000
|
@c2.class_eval do
|
|
986
|
-
|
|
1001
|
+
self::Foo = h
|
|
987
1002
|
def blah(x)
|
|
988
|
-
|
|
1003
|
+
model::Foo << (x ? x.pk : :x)
|
|
989
1004
|
end
|
|
990
1005
|
def blahr(x)
|
|
991
|
-
|
|
1006
|
+
model::Foo << 6
|
|
992
1007
|
end
|
|
993
1008
|
end
|
|
994
1009
|
p = @c2.load(:id=>10)
|
|
@@ -1004,13 +1019,11 @@ describe Sequel::Model, "one_to_one" do
|
|
|
1004
1019
|
h = []
|
|
1005
1020
|
@c2.one_to_one :parent, :class => @c2, :after_load=>[proc{|x,y| h << [x.pk, y.pk]}, :al]
|
|
1006
1021
|
@c2.class_eval do
|
|
1007
|
-
|
|
1022
|
+
self::Foo = h
|
|
1008
1023
|
def al(v)
|
|
1009
|
-
|
|
1010
|
-
end
|
|
1011
|
-
def @dataset.fetch_rows(sql)
|
|
1012
|
-
yield({:id=>20})
|
|
1024
|
+
model::Foo << v.pk
|
|
1013
1025
|
end
|
|
1026
|
+
@dataset._fetch = {:id=>20}
|
|
1014
1027
|
end
|
|
1015
1028
|
p = @c2.load(:id=>10)
|
|
1016
1029
|
parent = p.parent
|
|
@@ -1048,15 +1061,15 @@ describe Sequel::Model, "one_to_one" do
|
|
|
1048
1061
|
h = []
|
|
1049
1062
|
@c2.one_to_one :parent, :class => @c2, :before_set=>:bs, :after_set=>:as
|
|
1050
1063
|
@c2.class_eval do
|
|
1051
|
-
|
|
1064
|
+
self::Foo = h
|
|
1052
1065
|
def []=(a, v)
|
|
1053
|
-
a == :node_id ? (
|
|
1066
|
+
a == :node_id ? (model::Foo << 5) : super
|
|
1054
1067
|
end
|
|
1055
1068
|
def bs(x)
|
|
1056
|
-
|
|
1069
|
+
model::Foo << x.pk
|
|
1057
1070
|
end
|
|
1058
1071
|
def as(x)
|
|
1059
|
-
|
|
1072
|
+
model::Foo << x.pk * 2
|
|
1060
1073
|
end
|
|
1061
1074
|
end
|
|
1062
1075
|
p.parent = c
|
|
@@ -1072,16 +1085,9 @@ end
|
|
|
1072
1085
|
|
|
1073
1086
|
describe Sequel::Model, "one_to_many" do
|
|
1074
1087
|
before do
|
|
1075
|
-
MODEL_DB.reset
|
|
1076
|
-
|
|
1077
1088
|
@c1 = Class.new(Sequel::Model(:attributes)) do
|
|
1078
|
-
def _refresh(ds); end
|
|
1079
1089
|
unrestrict_primary_key
|
|
1080
1090
|
columns :id, :node_id, :y, :z
|
|
1081
|
-
|
|
1082
|
-
def self.[](id)
|
|
1083
|
-
load(id.is_a?(Array) ? {:id => id[0], :z => id[1]} : {:id => id})
|
|
1084
|
-
end
|
|
1085
1091
|
end
|
|
1086
1092
|
|
|
1087
1093
|
@c2 = Class.new(Sequel::Model(:nodes)) do
|
|
@@ -1094,68 +1100,58 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1094
1100
|
columns :id, :x
|
|
1095
1101
|
end
|
|
1096
1102
|
@dataset = @c2.dataset
|
|
1097
|
-
|
|
1098
|
-
@
|
|
1099
|
-
|
|
1100
|
-
def fetch_rows(sql)
|
|
1101
|
-
@db << sql
|
|
1102
|
-
yield Hash.new
|
|
1103
|
-
end
|
|
1104
|
-
})
|
|
1105
|
-
|
|
1106
|
-
@c1.dataset.extend(Module.new {
|
|
1107
|
-
def empty?; opts.has_key?(:empty) ? (super; true) : false; end
|
|
1108
|
-
def fetch_rows(sql)
|
|
1109
|
-
@db << sql
|
|
1110
|
-
yield Hash.new
|
|
1111
|
-
end
|
|
1112
|
-
})
|
|
1103
|
+
@dataset._fetch = {}
|
|
1104
|
+
@c1.dataset._fetch = proc{|sql| sql =~ /SELECT 1/ ? {:a=>1} : {}}
|
|
1105
|
+
MODEL_DB.reset
|
|
1113
1106
|
end
|
|
1114
1107
|
|
|
1115
1108
|
it "should use implicit key if omitted" do
|
|
1116
1109
|
@c2.one_to_many :attributes, :class => @c1
|
|
1117
|
-
|
|
1118
|
-
n = @c2.new(:id => 1234)
|
|
1119
|
-
a = n.attributes_dataset
|
|
1120
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
1121
|
-
a.sql.should == 'SELECT * FROM attributes WHERE (attributes.node_id = 1234)'
|
|
1110
|
+
@c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT * FROM attributes WHERE (attributes.node_id = 1234)'
|
|
1122
1111
|
end
|
|
1123
1112
|
|
|
1124
1113
|
it "should use implicit class if omitted" do
|
|
1125
|
-
|
|
1114
|
+
begin
|
|
1115
|
+
class ::HistoricalValue < Sequel::Model; end
|
|
1116
|
+
@c2.one_to_many :historical_values
|
|
1117
|
+
|
|
1118
|
+
v = @c2.new(:id => 1234).historical_values_dataset
|
|
1119
|
+
v.should be_a_kind_of(Sequel::Dataset)
|
|
1120
|
+
v.sql.should == 'SELECT * FROM historical_values WHERE (historical_values.node_id = 1234)'
|
|
1121
|
+
v.model.should == HistoricalValue
|
|
1122
|
+
ensure
|
|
1123
|
+
Object.send(:remove_const, :HistoricalValue)
|
|
1126
1124
|
end
|
|
1127
|
-
|
|
1128
|
-
@c2.one_to_many :historical_values
|
|
1129
|
-
|
|
1130
|
-
n = @c2.new(:id => 1234)
|
|
1131
|
-
v = n.historical_values_dataset
|
|
1132
|
-
v.should be_a_kind_of(Sequel::Dataset)
|
|
1133
|
-
v.sql.should == 'SELECT * FROM historical_values WHERE (historical_values.node_id = 1234)'
|
|
1134
|
-
v.model.should == HistoricalValue
|
|
1135
1125
|
end
|
|
1136
1126
|
|
|
1137
1127
|
it "should use class inside a module if given as a string" do
|
|
1138
|
-
|
|
1139
|
-
|
|
1128
|
+
begin
|
|
1129
|
+
module ::Historical
|
|
1130
|
+
class Value < Sequel::Model; end
|
|
1140
1131
|
end
|
|
1132
|
+
@c2.one_to_many :historical_values, :class=>'Historical::Value'
|
|
1133
|
+
|
|
1134
|
+
v = @c2.new(:id => 1234).historical_values_dataset
|
|
1135
|
+
v.should be_a_kind_of(Sequel::Dataset)
|
|
1136
|
+
v.sql.should == 'SELECT * FROM values WHERE (values.node_id = 1234)'
|
|
1137
|
+
v.model.should == Historical::Value
|
|
1138
|
+
ensure
|
|
1139
|
+
Object.send(:remove_const, :Historical)
|
|
1141
1140
|
end
|
|
1142
|
-
|
|
1143
|
-
@c2.one_to_many :historical_values, :class=>'Historical::Value'
|
|
1144
|
-
|
|
1145
|
-
n = @c2.new(:id => 1234)
|
|
1146
|
-
v = n.historical_values_dataset
|
|
1147
|
-
v.should be_a_kind_of(Sequel::Dataset)
|
|
1148
|
-
v.sql.should == 'SELECT * FROM values WHERE (values.node_id = 1234)'
|
|
1149
|
-
v.model.should == Historical::Value
|
|
1150
1141
|
end
|
|
1151
1142
|
|
|
1152
|
-
it "should use
|
|
1143
|
+
it "should use a callback if given one as the argument" do
|
|
1153
1144
|
@c2.one_to_many :attributes, :class => @c1, :key => :nodeid
|
|
1154
1145
|
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1146
|
+
d = @c2.load(:id => 1234)
|
|
1147
|
+
d.associations[:attributes] = []
|
|
1148
|
+
d.attributes(proc{|ds| ds.filter{name > 'M'}}).should_not == []
|
|
1149
|
+
MODEL_DB.sqls.should == ["SELECT * FROM attributes WHERE ((attributes.nodeid = 1234) AND (name > 'M'))"]
|
|
1150
|
+
end
|
|
1151
|
+
|
|
1152
|
+
it "should use explicit key if given" do
|
|
1153
|
+
@c2.one_to_many :attributes, :class => @c1, :key => :nodeid
|
|
1154
|
+
@c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT * FROM attributes WHERE (attributes.nodeid = 1234)'
|
|
1159
1155
|
end
|
|
1160
1156
|
|
|
1161
1157
|
it "should support_composite keys" do
|
|
@@ -1180,10 +1176,8 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1180
1176
|
it "should define an add_ method that works on existing records" do
|
|
1181
1177
|
@c2.one_to_many :attributes, :class => @c1
|
|
1182
1178
|
|
|
1183
|
-
n = @c2.
|
|
1184
|
-
a = @c1.
|
|
1185
|
-
a.save
|
|
1186
|
-
MODEL_DB.reset
|
|
1179
|
+
n = @c2.load(:id => 1234)
|
|
1180
|
+
a = @c1.load(:id => 2345)
|
|
1187
1181
|
a.should == n.add_attribute(a)
|
|
1188
1182
|
a.values.should == {:node_id => 1234, :id => 2345}
|
|
1189
1183
|
MODEL_DB.sqls.should == ['UPDATE attributes SET node_id = 1234 WHERE (id = 2345)']
|
|
@@ -1192,52 +1186,53 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1192
1186
|
it "should define an add_ method that works on new records" do
|
|
1193
1187
|
@c2.one_to_many :attributes, :class => @c1
|
|
1194
1188
|
|
|
1195
|
-
n = @c2.
|
|
1189
|
+
n = @c2.load(:id => 1234)
|
|
1196
1190
|
a = @c1.new(:id => 234)
|
|
1197
|
-
|
|
1198
|
-
MODEL_DB.reset
|
|
1191
|
+
@c1.dataset._fetch = @c1.instance_dataset._fetch = {:node_id => 1234, :id => 234}
|
|
1199
1192
|
a.should == n.add_attribute(a)
|
|
1200
|
-
MODEL_DB.sqls
|
|
1193
|
+
sqls = MODEL_DB.sqls
|
|
1194
|
+
sqls.shift.should =~ /INSERT INTO attributes \((node_)?id, (node_)?id\) VALUES \(1?234, 1?234\)/
|
|
1195
|
+
sqls.should == ["SELECT * FROM attributes WHERE (id = 234) LIMIT 1"]
|
|
1201
1196
|
a.values.should == {:node_id => 1234, :id => 234}
|
|
1202
1197
|
end
|
|
1203
1198
|
|
|
1204
1199
|
it "should define a remove_ method that works on existing records" do
|
|
1205
1200
|
@c2.one_to_many :attributes, :class => @c1
|
|
1206
1201
|
|
|
1207
|
-
n = @c2.
|
|
1208
|
-
a = @c1.
|
|
1209
|
-
a.save
|
|
1210
|
-
MODEL_DB.reset
|
|
1202
|
+
n = @c2.load(:id => 1234)
|
|
1203
|
+
a = @c1.load(:id => 2345, :node_id => 1234)
|
|
1211
1204
|
a.should == n.remove_attribute(a)
|
|
1212
1205
|
a.values.should == {:node_id => nil, :id => 2345}
|
|
1213
|
-
MODEL_DB.sqls.should == ['UPDATE attributes SET node_id = NULL WHERE (id = 2345)']
|
|
1206
|
+
MODEL_DB.sqls.should == ["SELECT 1 AS one FROM attributes WHERE ((attributes.node_id = 1234) AND (id = 2345)) LIMIT 1", 'UPDATE attributes SET node_id = NULL WHERE (id = 2345)']
|
|
1214
1207
|
end
|
|
1215
1208
|
|
|
1216
1209
|
it "should have the remove_ method raise an error if the passed object is not already associated" do
|
|
1217
1210
|
@c2.one_to_many :attributes, :class => @c1
|
|
1218
|
-
@c1.dataset.opts[:empty] = true
|
|
1219
1211
|
|
|
1220
1212
|
n = @c2.new(:id => 1234)
|
|
1221
1213
|
a = @c1.load(:id => 2345, :node_id => 1234)
|
|
1222
|
-
|
|
1214
|
+
@c1.dataset._fetch = []
|
|
1223
1215
|
proc{n.remove_attribute(a)}.should raise_error(Sequel::Error)
|
|
1224
|
-
MODEL_DB.sqls.should == ["SELECT 1 FROM attributes WHERE ((attributes.node_id = 1234) AND (id = 2345)) LIMIT 1"]
|
|
1216
|
+
MODEL_DB.sqls.should == ["SELECT 1 AS one FROM attributes WHERE ((attributes.node_id = 1234) AND (id = 2345)) LIMIT 1"]
|
|
1225
1217
|
end
|
|
1226
1218
|
|
|
1227
1219
|
it "should accept a hash for the add_ method and create a new record" do
|
|
1228
1220
|
@c2.one_to_many :attributes, :class => @c1
|
|
1229
1221
|
n = @c2.new(:id => 1234)
|
|
1230
1222
|
MODEL_DB.reset
|
|
1231
|
-
@c1.
|
|
1232
|
-
|
|
1223
|
+
@c1.dataset._fetch = @c1.instance_dataset._fetch = {:node_id => 1234, :id => 234}
|
|
1224
|
+
n.add_attribute(:id => 234).should == @c1.load(:node_id => 1234, :id => 234)
|
|
1225
|
+
sqls = MODEL_DB.sqls
|
|
1226
|
+
sqls.shift.should =~ /INSERT INTO attributes \((node_)?id, (node_)?id\) VALUES \(1?234, 1?234\)/
|
|
1227
|
+
sqls.should == ["SELECT * FROM attributes WHERE (id = 234) LIMIT 1"]
|
|
1233
1228
|
end
|
|
1234
1229
|
|
|
1235
1230
|
it "should accept a primary key for the add_ method" do
|
|
1236
1231
|
@c2.one_to_many :attributes, :class => @c1
|
|
1237
1232
|
n = @c2.new(:id => 1234)
|
|
1238
|
-
|
|
1239
|
-
@c1.load(:node_id => 1234, :id => 234)
|
|
1240
|
-
MODEL_DB.sqls.
|
|
1233
|
+
@c1.dataset._fetch = {:id=>234, :node_id=>nil}
|
|
1234
|
+
n.add_attribute(234).should == @c1.load(:node_id => 1234, :id => 234)
|
|
1235
|
+
MODEL_DB.sqls.should == ["SELECT * FROM attributes WHERE id = 234", "UPDATE attributes SET node_id = 1234 WHERE (id = 234)"]
|
|
1241
1236
|
end
|
|
1242
1237
|
|
|
1243
1238
|
it "should raise an error in the add_ method if the passed associated object is not of the correct type" do
|
|
@@ -1248,13 +1243,8 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1248
1243
|
it "should accept a primary key for the remove_ method and remove an existing record" do
|
|
1249
1244
|
@c2.one_to_many :attributes, :class => @c1
|
|
1250
1245
|
n = @c2.new(:id => 1234)
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
db << sql
|
|
1254
|
-
yield({:id=>234, :node_id=>1234})
|
|
1255
|
-
end
|
|
1256
|
-
MODEL_DB.reset
|
|
1257
|
-
@c1.load(:node_id => nil, :id => 234).should == n.remove_attribute(234)
|
|
1246
|
+
@c1.dataset._fetch = {:id=>234, :node_id=>1234}
|
|
1247
|
+
n.remove_attribute(234).should == @c1.load(:node_id => nil, :id => 234)
|
|
1258
1248
|
MODEL_DB.sqls.should == ['SELECT * FROM attributes WHERE ((attributes.node_id = 1234) AND (attributes.id = 234)) LIMIT 1',
|
|
1259
1249
|
'UPDATE attributes SET node_id = NULL WHERE (id = 234)']
|
|
1260
1250
|
end
|
|
@@ -1268,10 +1258,8 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1268
1258
|
@c2.one_to_many :attributes, :class => @c1, :primary_key=>:xxx
|
|
1269
1259
|
|
|
1270
1260
|
n = @c2.new(:id => 1234, :xxx=>5)
|
|
1271
|
-
a = @c1.
|
|
1272
|
-
a.
|
|
1273
|
-
MODEL_DB.reset
|
|
1274
|
-
a.should == n.add_attribute(a)
|
|
1261
|
+
a = @c1.load(:id => 2345)
|
|
1262
|
+
n.add_attribute(a).should == a
|
|
1275
1263
|
MODEL_DB.sqls.should == ['UPDATE attributes SET node_id = 5 WHERE (id = 2345)']
|
|
1276
1264
|
end
|
|
1277
1265
|
|
|
@@ -1279,15 +1267,13 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1279
1267
|
@c2.one_to_many :attributes, :class => @c1
|
|
1280
1268
|
|
|
1281
1269
|
n = @c2.new(:id => 1234)
|
|
1282
|
-
a = @c1.
|
|
1283
|
-
a.save
|
|
1284
|
-
MODEL_DB.reset
|
|
1270
|
+
a = @c1.load(:id => 2345)
|
|
1285
1271
|
n.associations[:attributes] = []
|
|
1286
1272
|
a.should == n.add_attribute(a)
|
|
1287
1273
|
a.should == n.add_attribute(a)
|
|
1288
1274
|
a.values.should == {:node_id => 1234, :id => 2345}
|
|
1289
|
-
MODEL_DB.sqls.should == ['UPDATE attributes SET node_id = 1234 WHERE (id = 2345)'] * 2
|
|
1290
1275
|
n.attributes.should == [a]
|
|
1276
|
+
MODEL_DB.sqls.should == ['UPDATE attributes SET node_id = 1234 WHERE (id = 2345)'] * 2
|
|
1291
1277
|
end
|
|
1292
1278
|
|
|
1293
1279
|
it "should have add_ method respect composite keys" do
|
|
@@ -1295,18 +1281,24 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1295
1281
|
|
|
1296
1282
|
n = @c2.load(:id => 1234, :x=>5)
|
|
1297
1283
|
a = @c1.load(:id => 2345)
|
|
1298
|
-
a.should ==
|
|
1299
|
-
|
|
1284
|
+
n.add_attribute(a).should == a
|
|
1285
|
+
sqls = MODEL_DB.sqls
|
|
1286
|
+
sqls.shift.should =~ /UPDATE attributes SET (node_id = 1234|y = 5), (node_id = 1234|y = 5) WHERE \(id = 2345\)/
|
|
1287
|
+
sqls.should == []
|
|
1300
1288
|
end
|
|
1301
1289
|
|
|
1302
1290
|
it "should have add_ method accept a composite key" do
|
|
1303
1291
|
@c1.set_primary_key :id, :z
|
|
1304
1292
|
@c2.one_to_many :attributes, :class => @c1, :key =>[:node_id, :y], :primary_key=>[:id, :x]
|
|
1293
|
+
@c1.dataset._fetch = {:id => 2345, :z => 8, :node_id => 1234, :y=>5}
|
|
1305
1294
|
|
|
1306
1295
|
n = @c2.load(:id => 1234, :x=>5)
|
|
1307
1296
|
a = @c1.load(:id => 2345, :z => 8, :node_id => 1234, :y=>5)
|
|
1308
|
-
|
|
1309
|
-
|
|
1297
|
+
n.add_attribute([2345, 8]).should == a
|
|
1298
|
+
sqls = MODEL_DB.sqls
|
|
1299
|
+
sqls.shift.should =~ /SELECT \* FROM attributes WHERE \(\((id|z) = (2345|8)\) AND \((id|z) = (2345|8)\)\) LIMIT 1/
|
|
1300
|
+
sqls.shift.should =~ /UPDATE attributes SET (node_id|y) = (1234|5), (node_id|y) = (1234|5) WHERE \(\((id|z) = (2345|8)\) AND \((id|z) = (2345|8)\)\)/
|
|
1301
|
+
sqls.should == []
|
|
1310
1302
|
end
|
|
1311
1303
|
|
|
1312
1304
|
it "should have remove_ method respect composite keys" do
|
|
@@ -1314,31 +1306,29 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1314
1306
|
|
|
1315
1307
|
n = @c2.load(:id => 1234, :x=>5)
|
|
1316
1308
|
a = @c1.load(:id => 2345, :node_id=>1234, :y=>5)
|
|
1317
|
-
a.should ==
|
|
1318
|
-
|
|
1309
|
+
n.remove_attribute(a).should == a
|
|
1310
|
+
sqls = MODEL_DB.sqls
|
|
1311
|
+
sqls.pop.should =~ /UPDATE attributes SET (node_id|y) = NULL, (node_id|y) = NULL WHERE \(id = 2345\)/
|
|
1312
|
+
sqls.should == ["SELECT 1 AS one FROM attributes WHERE ((attributes.node_id = 1234) AND (attributes.y = 5) AND (id = 2345)) LIMIT 1"]
|
|
1319
1313
|
end
|
|
1320
1314
|
|
|
1321
1315
|
it "should accept a array of composite primary key values for the remove_ method and remove an existing record" do
|
|
1322
1316
|
@c1.set_primary_key :id, :y
|
|
1323
1317
|
@c2.one_to_many :attributes, :class => @c1, :key=>:node_id, :primary_key=>:id
|
|
1324
1318
|
n = @c2.new(:id => 123)
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
@c1.load(:node_id => nil, :y => 5, :id => 234).should == n.remove_attribute([234, 5])
|
|
1332
|
-
MODEL_DB.sqls.length.should == 2
|
|
1333
|
-
MODEL_DB.sqls.first.should =~ /SELECT \* FROM attributes WHERE \(\(attributes.node_id = 123\) AND \(attributes\.(id|y) = (234|5)\) AND \(attributes\.(id|y) = (234|5)\)\) LIMIT 1/
|
|
1334
|
-
MODEL_DB.sqls.last.should =~ /UPDATE attributes SET node_id = NULL WHERE \(\((id|y) = (234|5)\) AND \((id|y) = (234|5)\)\)/
|
|
1319
|
+
@c1.dataset._fetch = {:id=>234, :node_id=>123, :y=>5}
|
|
1320
|
+
n.remove_attribute([234, 5]).should == @c1.load(:node_id => nil, :y => 5, :id => 234)
|
|
1321
|
+
sqls = MODEL_DB.sqls
|
|
1322
|
+
sqls.length.should == 2
|
|
1323
|
+
sqls.first.should =~ /SELECT \* FROM attributes WHERE \(\(attributes.node_id = 123\) AND \(attributes\.(id|y) = (234|5)\) AND \(attributes\.(id|y) = (234|5)\)\) LIMIT 1/
|
|
1324
|
+
sqls.last.should =~ /UPDATE attributes SET node_id = NULL WHERE \(\((id|y) = (234|5)\) AND \((id|y) = (234|5)\)\)/
|
|
1335
1325
|
end
|
|
1336
1326
|
|
|
1337
1327
|
it "should raise an error in add_ and remove_ if the passed object returns false to save (is not valid)" do
|
|
1338
1328
|
@c2.one_to_many :attributes, :class => @c1
|
|
1339
1329
|
n = @c2.new(:id => 1234)
|
|
1340
1330
|
a = @c1.new(:id => 2345)
|
|
1341
|
-
def a.
|
|
1331
|
+
def a.validate() errors.add(:id, 'foo') end
|
|
1342
1332
|
proc{n.add_attribute(a)}.should raise_error(Sequel::Error)
|
|
1343
1333
|
proc{n.remove_attribute(a)}.should raise_error(Sequel::Error)
|
|
1344
1334
|
end
|
|
@@ -1347,7 +1337,7 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1347
1337
|
@c2.one_to_many :attributes, :class => @c1, :validate=>false
|
|
1348
1338
|
n = @c2.new(:id => 1234)
|
|
1349
1339
|
a = @c1.new(:id => 2345)
|
|
1350
|
-
def a.
|
|
1340
|
+
def a.validate() errors.add(:id, 'foo') end
|
|
1351
1341
|
n.add_attribute(a).should == a
|
|
1352
1342
|
n.remove_attribute(a).should == a
|
|
1353
1343
|
end
|
|
@@ -1364,81 +1354,48 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1364
1354
|
|
|
1365
1355
|
it "should use :primary_key option if given" do
|
|
1366
1356
|
@c1.one_to_many :nodes, :class => @c2, :primary_key => :node_id, :key=>:id
|
|
1367
|
-
|
|
1368
|
-
n.nodes_dataset.sql.should == "SELECT * FROM nodes WHERE (nodes.id = 4321)"
|
|
1357
|
+
@c1.load(:id => 1234, :node_id=>4321).nodes_dataset.sql.should == "SELECT * FROM nodes WHERE (nodes.id = 4321)"
|
|
1369
1358
|
end
|
|
1370
1359
|
|
|
1371
1360
|
it "should support a select option" do
|
|
1372
1361
|
@c2.one_to_many :attributes, :class => @c1, :select => [:id, :name]
|
|
1373
|
-
|
|
1374
|
-
n = @c2.new(:id => 1234)
|
|
1375
|
-
n.attributes_dataset.sql.should == "SELECT id, name FROM attributes WHERE (attributes.node_id = 1234)"
|
|
1362
|
+
@c2.new(:id => 1234).attributes_dataset.sql.should == "SELECT id, name FROM attributes WHERE (attributes.node_id = 1234)"
|
|
1376
1363
|
end
|
|
1377
1364
|
|
|
1378
1365
|
it "should support a conditions option" do
|
|
1379
1366
|
@c2.one_to_many :attributes, :class => @c1, :conditions => {:a=>32}
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
@c2.
|
|
1383
|
-
n = @c2.new(:id => 1234)
|
|
1384
|
-
n.attributes_dataset.sql.should == "SELECT * FROM attributes WHERE ((attributes.node_id = 1234) AND NOT a)"
|
|
1367
|
+
@c2.new(:id => 1234).attributes_dataset.sql.should == "SELECT * FROM attributes WHERE ((attributes.node_id = 1234) AND (a = 32))"
|
|
1368
|
+
@c2.one_to_many :attributes, :class => @c1, :conditions => Sequel.~(:a)
|
|
1369
|
+
@c2.new(:id => 1234).attributes_dataset.sql.should == "SELECT * FROM attributes WHERE ((attributes.node_id = 1234) AND NOT a)"
|
|
1385
1370
|
end
|
|
1386
1371
|
|
|
1387
1372
|
it "should support an order option" do
|
|
1388
1373
|
@c2.one_to_many :attributes, :class => @c1, :order => :kind
|
|
1389
|
-
|
|
1390
|
-
n = @c2.new(:id => 1234)
|
|
1391
|
-
n.attributes_dataset.sql.should == "SELECT * FROM attributes WHERE (attributes.node_id = 1234) ORDER BY kind"
|
|
1374
|
+
@c2.new(:id => 1234).attributes_dataset.sql.should == "SELECT * FROM attributes WHERE (attributes.node_id = 1234) ORDER BY kind"
|
|
1392
1375
|
end
|
|
1393
1376
|
|
|
1394
1377
|
it "should support an array for the order option" do
|
|
1395
1378
|
@c2.one_to_many :attributes, :class => @c1, :order => [:kind1, :kind2]
|
|
1396
|
-
|
|
1397
|
-
n = @c2.new(:id => 1234)
|
|
1398
|
-
n.attributes_dataset.sql.should == "SELECT * FROM attributes WHERE (attributes.node_id = 1234) ORDER BY kind1, kind2"
|
|
1379
|
+
@c2.new(:id => 1234).attributes_dataset.sql.should == "SELECT * FROM attributes WHERE (attributes.node_id = 1234) ORDER BY kind1, kind2"
|
|
1399
1380
|
end
|
|
1400
1381
|
|
|
1401
1382
|
it "should return array with all members of the association" do
|
|
1402
1383
|
@c2.one_to_many :attributes, :class => @c1
|
|
1403
|
-
|
|
1404
|
-
n = @c2.new(:id => 1234)
|
|
1405
|
-
atts = n.attributes
|
|
1406
|
-
atts.should be_a_kind_of(Array)
|
|
1407
|
-
atts.size.should == 1
|
|
1408
|
-
atts.first.should be_a_kind_of(@c1)
|
|
1409
|
-
atts.first.values.should == {}
|
|
1410
|
-
|
|
1411
|
-
MODEL_DB.sqls.should == ['SELECT * FROM attributes WHERE (attributes.node_id = 1234)']
|
|
1384
|
+
@c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT * FROM attributes WHERE (attributes.node_id = 1234)'
|
|
1412
1385
|
end
|
|
1413
1386
|
|
|
1414
1387
|
it "should accept a block" do
|
|
1415
1388
|
@c2.one_to_many :attributes, :class => @c1 do |ds|
|
|
1416
1389
|
ds.filter(:xxx => @xxx)
|
|
1417
1390
|
end
|
|
1418
|
-
|
|
1419
|
-
n = @c2.new(:id => 1234)
|
|
1420
|
-
atts = n.attributes
|
|
1421
|
-
atts.should be_a_kind_of(Array)
|
|
1422
|
-
atts.size.should == 1
|
|
1423
|
-
atts.first.should be_a_kind_of(@c1)
|
|
1424
|
-
atts.first.values.should == {}
|
|
1425
|
-
|
|
1426
|
-
MODEL_DB.sqls.should == ['SELECT * FROM attributes WHERE ((attributes.node_id = 1234) AND (xxx IS NULL))']
|
|
1391
|
+
@c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT * FROM attributes WHERE ((attributes.node_id = 1234) AND (xxx IS NULL))'
|
|
1427
1392
|
end
|
|
1428
1393
|
|
|
1429
1394
|
it "should support :order option with block" do
|
|
1430
1395
|
@c2.one_to_many :attributes, :class => @c1, :order => :kind do |ds|
|
|
1431
1396
|
ds.filter(:xxx => @xxx)
|
|
1432
1397
|
end
|
|
1433
|
-
|
|
1434
|
-
n = @c2.new(:id => 1234)
|
|
1435
|
-
atts = n.attributes
|
|
1436
|
-
atts.should be_a_kind_of(Array)
|
|
1437
|
-
atts.size.should == 1
|
|
1438
|
-
atts.first.should be_a_kind_of(@c1)
|
|
1439
|
-
atts.first.values.should == {}
|
|
1440
|
-
|
|
1441
|
-
MODEL_DB.sqls.should == ['SELECT * FROM attributes WHERE ((attributes.node_id = 1234) AND (xxx IS NULL)) ORDER BY kind']
|
|
1398
|
+
@c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT * FROM attributes WHERE ((attributes.node_id = 1234) AND (xxx IS NULL)) ORDER BY kind'
|
|
1442
1399
|
end
|
|
1443
1400
|
|
|
1444
1401
|
it "should have the block argument affect the _dataset method" do
|
|
@@ -1450,18 +1407,11 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1450
1407
|
|
|
1451
1408
|
it "should support a :dataset option that is used instead of the default" do
|
|
1452
1409
|
c1 = @c1
|
|
1453
|
-
@c2.one_to_many :all_other_attributes, :class => @c1, :dataset=>proc{c1.
|
|
1410
|
+
@c2.one_to_many :all_other_attributes, :class => @c1, :dataset=>proc{c1.exclude(:nodeid=>pk)}, :order=>:a, :limit=>10 do |ds|
|
|
1454
1411
|
ds.filter(:xxx => 5)
|
|
1455
1412
|
end
|
|
1456
|
-
|
|
1457
1413
|
@c2.new(:id => 1234).all_other_attributes_dataset.sql.should == 'SELECT * FROM attributes WHERE ((nodeid != 1234) AND (xxx = 5)) ORDER BY a LIMIT 10'
|
|
1458
|
-
|
|
1459
|
-
atts = n.all_other_attributes
|
|
1460
|
-
atts.should be_a_kind_of(Array)
|
|
1461
|
-
atts.size.should == 1
|
|
1462
|
-
atts.first.should be_a_kind_of(@c1)
|
|
1463
|
-
atts.first.values.should == {}
|
|
1464
|
-
|
|
1414
|
+
@c2.new(:id => 1234).all_other_attributes.should == [@c1.load({})]
|
|
1465
1415
|
MODEL_DB.sqls.should == ['SELECT * FROM attributes WHERE ((nodeid != 1234) AND (xxx = 5)) ORDER BY a LIMIT 10']
|
|
1466
1416
|
end
|
|
1467
1417
|
|
|
@@ -1479,9 +1429,7 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1479
1429
|
|
|
1480
1430
|
it "should set cached instance variable when accessed" do
|
|
1481
1431
|
@c2.one_to_many :attributes, :class => @c1
|
|
1482
|
-
|
|
1483
1432
|
n = @c2.new(:id => 1234)
|
|
1484
|
-
MODEL_DB.reset
|
|
1485
1433
|
n.associations.include?(:attributes).should == false
|
|
1486
1434
|
atts = n.attributes
|
|
1487
1435
|
atts.should == n.associations[:attributes]
|
|
@@ -1490,9 +1438,7 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1490
1438
|
|
|
1491
1439
|
it "should use cached instance variable if available" do
|
|
1492
1440
|
@c2.one_to_many :attributes, :class => @c1
|
|
1493
|
-
|
|
1494
1441
|
n = @c2.new(:id => 1234)
|
|
1495
|
-
MODEL_DB.reset
|
|
1496
1442
|
n.associations[:attributes] = 42
|
|
1497
1443
|
n.attributes.should == 42
|
|
1498
1444
|
MODEL_DB.sqls.should == []
|
|
@@ -1500,9 +1446,7 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1500
1446
|
|
|
1501
1447
|
it "should not use cached instance variable if asked to reload" do
|
|
1502
1448
|
@c2.one_to_many :attributes, :class => @c1
|
|
1503
|
-
|
|
1504
1449
|
n = @c2.new(:id => 1234)
|
|
1505
|
-
MODEL_DB.reset
|
|
1506
1450
|
n.associations[:attributes] = 42
|
|
1507
1451
|
n.attributes(true).should_not == 42
|
|
1508
1452
|
MODEL_DB.sqls.should == ['SELECT * FROM attributes WHERE (attributes.node_id = 1234)']
|
|
@@ -1510,10 +1454,8 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1510
1454
|
|
|
1511
1455
|
it "should add item to cached instance variable if it exists when calling add_" do
|
|
1512
1456
|
@c2.one_to_many :attributes, :class => @c1
|
|
1513
|
-
|
|
1514
1457
|
n = @c2.new(:id => 1234)
|
|
1515
|
-
att = @c1.
|
|
1516
|
-
MODEL_DB.reset
|
|
1458
|
+
att = @c1.load(:id => 345)
|
|
1517
1459
|
a = []
|
|
1518
1460
|
n.associations[:attributes] = a
|
|
1519
1461
|
n.add_attribute(att)
|
|
@@ -1535,7 +1477,6 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1535
1477
|
|
|
1536
1478
|
n = @c2.load(:id => 1234)
|
|
1537
1479
|
att = @c1.load(:id => 345)
|
|
1538
|
-
MODEL_DB.reset
|
|
1539
1480
|
a = [att]
|
|
1540
1481
|
n.associations[:attributes] = a
|
|
1541
1482
|
n.remove_attribute(att)
|
|
@@ -1587,13 +1528,9 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1587
1528
|
n = @c2.new(:id => 1234)
|
|
1588
1529
|
atts = n.attributes
|
|
1589
1530
|
MODEL_DB.sqls.should == ['SELECT * FROM attributes WHERE (attributes.node_id = 1234)']
|
|
1590
|
-
atts.should
|
|
1591
|
-
atts.
|
|
1592
|
-
|
|
1593
|
-
atts.first.values.should == {}
|
|
1594
|
-
atts.first.node.should == n
|
|
1595
|
-
|
|
1596
|
-
MODEL_DB.sqls.length.should == 1
|
|
1531
|
+
atts.should == [@c1.load({})]
|
|
1532
|
+
atts.map{|a| a.node}.should == [n]
|
|
1533
|
+
MODEL_DB.sqls.should == []
|
|
1597
1534
|
end
|
|
1598
1535
|
|
|
1599
1536
|
it "should use an explicit reciprocal instance variable if given" do
|
|
@@ -1602,19 +1539,15 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1602
1539
|
n = @c2.new(:id => 1234)
|
|
1603
1540
|
atts = n.attributes
|
|
1604
1541
|
MODEL_DB.sqls.should == ['SELECT * FROM attributes WHERE (attributes.node_id = 1234)']
|
|
1605
|
-
atts.should
|
|
1606
|
-
atts.
|
|
1607
|
-
|
|
1608
|
-
atts.first.values.should == {}
|
|
1609
|
-
atts.first.associations[:wxyz].should == n
|
|
1610
|
-
|
|
1611
|
-
MODEL_DB.sqls.length.should == 1
|
|
1542
|
+
atts.should == [@c1.load({})]
|
|
1543
|
+
atts.map{|a| a.associations[:wxyz]}.should == [n]
|
|
1544
|
+
MODEL_DB.sqls.should == []
|
|
1612
1545
|
end
|
|
1613
1546
|
|
|
1614
1547
|
it "should have an remove_all_ method that removes all associations" do
|
|
1615
1548
|
@c2.one_to_many :attributes, :class => @c1
|
|
1616
1549
|
@c2.new(:id => 1234).remove_all_attributes
|
|
1617
|
-
MODEL_DB.sqls.
|
|
1550
|
+
MODEL_DB.sqls.should == ['UPDATE attributes SET node_id = NULL WHERE (node_id = 1234)']
|
|
1618
1551
|
end
|
|
1619
1552
|
|
|
1620
1553
|
it "should have remove_all method respect association filters" do
|
|
@@ -1628,13 +1561,15 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1628
1561
|
it "should have the remove_all_ method respect the :primary_key option" do
|
|
1629
1562
|
@c2.one_to_many :attributes, :class => @c1, :primary_key=>:xxx
|
|
1630
1563
|
@c2.new(:id => 1234, :xxx=>5).remove_all_attributes
|
|
1631
|
-
MODEL_DB.sqls.
|
|
1564
|
+
MODEL_DB.sqls.should == ['UPDATE attributes SET node_id = NULL WHERE (node_id = 5)']
|
|
1632
1565
|
end
|
|
1633
1566
|
|
|
1634
1567
|
it "should have the remove_all_ method respect composite keys" do
|
|
1635
1568
|
@c2.one_to_many :attributes, :class => @c1, :key=>[:node_id, :y], :primary_key=>[:id, :x]
|
|
1636
1569
|
@c2.new(:id => 1234, :x=>5).remove_all_attributes
|
|
1637
|
-
|
|
1570
|
+
sqls = MODEL_DB.sqls
|
|
1571
|
+
sqls.pop.should =~ /UPDATE attributes SET (node_id|y) = NULL, (node_id|y) = NULL WHERE \(\(node_id = 1234\) AND \(y = 5\)\)/
|
|
1572
|
+
sqls.should == []
|
|
1638
1573
|
end
|
|
1639
1574
|
|
|
1640
1575
|
it "remove_all should set the cached instance variable to []" do
|
|
@@ -1648,10 +1583,8 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1648
1583
|
@c2.one_to_many :attributes, :class => @c1
|
|
1649
1584
|
attrib = @c1.new(:id=>3)
|
|
1650
1585
|
node = @c2.new(:id => 1234)
|
|
1651
|
-
|
|
1652
|
-
def d.fetch_rows(s); end
|
|
1586
|
+
@c1.dataset._fetch = [[], [{:id=>3, :node_id=>1234}]]
|
|
1653
1587
|
node.attributes.should == []
|
|
1654
|
-
def attrib.save(*); self end
|
|
1655
1588
|
node.add_attribute(attrib)
|
|
1656
1589
|
node.associations[:attributes].should == [attrib]
|
|
1657
1590
|
node.remove_all_attributes.should == [attrib]
|
|
@@ -1665,15 +1598,12 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1665
1598
|
it "remove_all should remove the current item from all reciprocal instance varaibles if it cached instance variable exists" do
|
|
1666
1599
|
@c2.one_to_many :attributes, :class => @c1
|
|
1667
1600
|
@c1.many_to_one :node, :class => @c2
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
d = @c2.dataset
|
|
1671
|
-
def d.fetch_rows(s); end
|
|
1601
|
+
@c2.dataset._fetch = []
|
|
1602
|
+
@c1.dataset._fetch = [[], [{:id=>3, :node_id=>1234}]]
|
|
1672
1603
|
attrib = @c1.new(:id=>3)
|
|
1673
|
-
node = @c2.
|
|
1604
|
+
node = @c2.load(:id => 1234)
|
|
1674
1605
|
node.attributes.should == []
|
|
1675
1606
|
attrib.node.should == nil
|
|
1676
|
-
def attrib.save(*); self end
|
|
1677
1607
|
node.add_attribute(attrib)
|
|
1678
1608
|
attrib.associations[:node].should == node
|
|
1679
1609
|
node.remove_all_attributes
|
|
@@ -1761,18 +1691,18 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1761
1691
|
h = []
|
|
1762
1692
|
@c2.one_to_many :attributes, :class => @c1, :before_add=>[proc{|x,y| h << x.pk; h << -y.pk}, :blah], :after_add=>proc{h << 3}, :before_remove=>:blah, :after_remove=>[:blahr]
|
|
1763
1693
|
@c2.class_eval do
|
|
1764
|
-
|
|
1694
|
+
self::Foo = h
|
|
1765
1695
|
def _add_attribute(v)
|
|
1766
|
-
|
|
1696
|
+
model::Foo << 4
|
|
1767
1697
|
end
|
|
1768
1698
|
def _remove_attribute(v)
|
|
1769
|
-
|
|
1699
|
+
model::Foo << 5
|
|
1770
1700
|
end
|
|
1771
1701
|
def blah(x)
|
|
1772
|
-
|
|
1702
|
+
model::Foo << x.pk
|
|
1773
1703
|
end
|
|
1774
1704
|
def blahr(x)
|
|
1775
|
-
|
|
1705
|
+
model::Foo << 6
|
|
1776
1706
|
end
|
|
1777
1707
|
end
|
|
1778
1708
|
p = @c2.load(:id=>10)
|
|
@@ -1788,17 +1718,12 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1788
1718
|
h = []
|
|
1789
1719
|
@c2.one_to_many :attributes, :class => @c1, :after_load=>[proc{|x,y| h << [x.pk, y.collect{|z|z.pk}]}, :al]
|
|
1790
1720
|
@c2.class_eval do
|
|
1791
|
-
|
|
1721
|
+
self::Foo = h
|
|
1792
1722
|
def al(v)
|
|
1793
|
-
v.each{|x|
|
|
1794
|
-
end
|
|
1795
|
-
end
|
|
1796
|
-
@c1.class_eval do
|
|
1797
|
-
def @dataset.fetch_rows(sql)
|
|
1798
|
-
yield({:id=>20})
|
|
1799
|
-
yield({:id=>30})
|
|
1723
|
+
v.each{|x| model::Foo << x.pk}
|
|
1800
1724
|
end
|
|
1801
1725
|
end
|
|
1726
|
+
@c1.dataset._fetch = [{:id=>20}, {:id=>30}]
|
|
1802
1727
|
p = @c2.load(:id=>10, :parent_id=>20)
|
|
1803
1728
|
attributes = p.attributes
|
|
1804
1729
|
h.should == [[10, [20, 30]], 20, 30]
|
|
@@ -1845,23 +1770,13 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1845
1770
|
end
|
|
1846
1771
|
|
|
1847
1772
|
describe Sequel::Model, "many_to_many" do
|
|
1848
|
-
|
|
1849
1773
|
before do
|
|
1850
|
-
MODEL_DB.reset
|
|
1851
|
-
|
|
1852
1774
|
@c1 = Class.new(Sequel::Model(:attributes)) do
|
|
1853
1775
|
unrestrict_primary_key
|
|
1854
1776
|
attr_accessor :yyy
|
|
1855
1777
|
def self.name; 'Attribute'; end
|
|
1856
1778
|
def self.to_s; 'Attribute'; end
|
|
1857
|
-
columns :id, :y
|
|
1858
|
-
def _refresh(ds)
|
|
1859
|
-
self
|
|
1860
|
-
end
|
|
1861
|
-
|
|
1862
|
-
def self.[](id)
|
|
1863
|
-
load(id.is_a?(Array) ? {:id => id[0], :y => id[1]} : {:id => id})
|
|
1864
|
-
end
|
|
1779
|
+
columns :id, :y, :z
|
|
1865
1780
|
end
|
|
1866
1781
|
|
|
1867
1782
|
@c2 = Class.new(Sequel::Model(:nodes)) do
|
|
@@ -1873,98 +1788,66 @@ describe Sequel::Model, "many_to_many" do
|
|
|
1873
1788
|
columns :id, :x
|
|
1874
1789
|
end
|
|
1875
1790
|
@dataset = @c2.dataset
|
|
1791
|
+
@c1.dataset.autoid = 1
|
|
1876
1792
|
|
|
1877
|
-
[@c1, @c2].each
|
|
1878
|
-
|
|
1879
|
-
def fetch_rows(sql)
|
|
1880
|
-
@db << sql
|
|
1881
|
-
yield Hash.new
|
|
1882
|
-
end
|
|
1883
|
-
})
|
|
1884
|
-
end
|
|
1793
|
+
[@c1, @c2].each{|c| c.dataset._fetch = {}}
|
|
1794
|
+
MODEL_DB.reset
|
|
1885
1795
|
end
|
|
1886
1796
|
|
|
1887
1797
|
it "should use implicit key values and join table if omitted" do
|
|
1888
1798
|
@c2.many_to_many :attributes, :class => @c1
|
|
1889
|
-
|
|
1890
|
-
n = @c2.new(:id => 1234)
|
|
1891
|
-
a = n.attributes_dataset
|
|
1892
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
1893
|
-
a.sql.should == 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234))'
|
|
1799
|
+
@c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234))'
|
|
1894
1800
|
end
|
|
1895
1801
|
|
|
1896
1802
|
it "should use implicit class if omitted" do
|
|
1897
|
-
|
|
1803
|
+
begin
|
|
1804
|
+
class ::Tag < Sequel::Model; end
|
|
1805
|
+
@c2.many_to_many :tags
|
|
1806
|
+
@c2.new(:id => 1234).tags_dataset.sql.should == 'SELECT tags.* FROM tags INNER JOIN nodes_tags ON ((nodes_tags.tag_id = tags.id) AND (nodes_tags.node_id = 1234))'
|
|
1807
|
+
ensure
|
|
1808
|
+
Object.send(:remove_const, :Tag)
|
|
1898
1809
|
end
|
|
1899
|
-
|
|
1900
|
-
@c2.many_to_many :tags
|
|
1901
|
-
|
|
1902
|
-
n = @c2.new(:id => 1234)
|
|
1903
|
-
a = n.tags_dataset
|
|
1904
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
1905
|
-
a.sql.should == 'SELECT tags.* FROM tags INNER JOIN nodes_tags ON ((nodes_tags.tag_id = tags.id) AND (nodes_tags.node_id = 1234))'
|
|
1906
1810
|
end
|
|
1907
1811
|
|
|
1908
1812
|
it "should use class inside module if given as a string" do
|
|
1909
|
-
|
|
1910
|
-
|
|
1813
|
+
begin
|
|
1814
|
+
module ::Historical
|
|
1815
|
+
class Tag < Sequel::Model; end
|
|
1911
1816
|
end
|
|
1817
|
+
@c2.many_to_many :tags, :class=>'::Historical::Tag'
|
|
1818
|
+
@c2.new(:id => 1234).tags_dataset.sql.should == 'SELECT tags.* FROM tags INNER JOIN nodes_tags ON ((nodes_tags.tag_id = tags.id) AND (nodes_tags.node_id = 1234))'
|
|
1819
|
+
ensure
|
|
1820
|
+
Object.send(:remove_const, :Historical)
|
|
1912
1821
|
end
|
|
1913
|
-
|
|
1914
|
-
@c2.many_to_many :tags, :class=>'::Historical::Tag'
|
|
1915
|
-
|
|
1916
|
-
n = @c2.new(:id => 1234)
|
|
1917
|
-
a = n.tags_dataset
|
|
1918
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
1919
|
-
a.sql.should == 'SELECT tags.* FROM tags INNER JOIN nodes_tags ON ((nodes_tags.tag_id = tags.id) AND (nodes_tags.node_id = 1234))'
|
|
1920
1822
|
end
|
|
1921
1823
|
|
|
1922
|
-
it "should
|
|
1923
|
-
@c2.many_to_many :attributes, :class => @c1, :
|
|
1924
|
-
|
|
1925
|
-
n = @c2.new(:id => 1234)
|
|
1926
|
-
a = n.attributes_dataset
|
|
1927
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
1928
|
-
a.sql.should == 'SELECT attributes.* FROM attributes INNER JOIN attribute2node ON ((attribute2node.attributeid = attributes.id) AND (attribute2node.nodeid = 1234))'
|
|
1824
|
+
it "should respect :eager_loader_predicate_key when lazily loading" do
|
|
1825
|
+
@c2.many_to_many :attributes, :class => @c1, :eager_loading_predicate_key=>Sequel.subscript(:attributes_nodes__node_id, 0)
|
|
1826
|
+
@c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id[0] = 1234))'
|
|
1929
1827
|
end
|
|
1930
1828
|
|
|
1931
|
-
it "should
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
a = @c2.eager_loading_dataset(r, @c2.dataset, [:id], nil)
|
|
1935
|
-
a.sql.should == 'SELECT id, attributes_nodes.node_id AS x_foreign_key_x FROM nodes'
|
|
1829
|
+
it "should use explicit key values and join table if given" do
|
|
1830
|
+
@c2.many_to_many :attributes, :class => @c1, :left_key => :nodeid, :right_key => :attributeid, :join_table => :attribute2node
|
|
1831
|
+
@c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT attributes.* FROM attributes INNER JOIN attribute2node ON ((attribute2node.attributeid = attributes.id) AND (attribute2node.nodeid = 1234))'
|
|
1936
1832
|
end
|
|
1937
1833
|
|
|
1938
1834
|
it "should support a conditions option" do
|
|
1939
1835
|
@c2.many_to_many :attributes, :class => @c1, :conditions => {:a=>32}
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
1943
|
-
a.sql.should == 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234)) WHERE (a = 32)'
|
|
1836
|
+
@c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234)) WHERE (a = 32)'
|
|
1837
|
+
|
|
1944
1838
|
@c2.many_to_many :attributes, :class => @c1, :conditions => ['a = ?', 32]
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
1948
|
-
a.sql.should == 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234)) WHERE (a = 32)'
|
|
1949
|
-
n.attributes.should == [@c1.load({})]
|
|
1839
|
+
@c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234)) WHERE (a = 32)'
|
|
1840
|
+
@c2.new(:id => 1234).attributes.should == [@c1.load({})]
|
|
1950
1841
|
end
|
|
1951
1842
|
|
|
1952
1843
|
it "should support an order option" do
|
|
1953
1844
|
@c2.many_to_many :attributes, :class => @c1, :order => :blah
|
|
1954
|
-
|
|
1955
|
-
n = @c2.new(:id => 1234)
|
|
1956
|
-
a = n.attributes_dataset
|
|
1957
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
1958
|
-
a.sql.should == 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234)) ORDER BY blah'
|
|
1845
|
+
@c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234)) ORDER BY blah'
|
|
1959
1846
|
end
|
|
1960
1847
|
|
|
1961
1848
|
it "should support an array for the order option" do
|
|
1962
1849
|
@c2.many_to_many :attributes, :class => @c1, :order => [:blah1, :blah2]
|
|
1963
|
-
|
|
1964
|
-
n = @c2.new(:id => 1234)
|
|
1965
|
-
a = n.attributes_dataset
|
|
1966
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
1967
|
-
a.sql.should == 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234)) ORDER BY blah1, blah2'
|
|
1850
|
+
@c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234)) ORDER BY blah1, blah2'
|
|
1968
1851
|
end
|
|
1969
1852
|
|
|
1970
1853
|
it "should support :left_primary_key and :right_primary_key options" do
|
|
@@ -1999,19 +1882,13 @@ describe Sequel::Model, "many_to_many" do
|
|
|
1999
1882
|
it "should support a select option" do
|
|
2000
1883
|
@c2.many_to_many :attributes, :class => @c1, :select => :blah
|
|
2001
1884
|
|
|
2002
|
-
|
|
2003
|
-
a = n.attributes_dataset
|
|
2004
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
2005
|
-
a.sql.should == 'SELECT blah FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234))'
|
|
1885
|
+
@c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT blah FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234))'
|
|
2006
1886
|
end
|
|
2007
1887
|
|
|
2008
1888
|
it "should support an array for the select option" do
|
|
2009
|
-
@c2.many_to_many :attributes, :class => @c1, :select => [:attributes
|
|
1889
|
+
@c2.many_to_many :attributes, :class => @c1, :select => [Sequel::SQL::ColumnAll.new(:attributes), :attribute_nodes__blah2]
|
|
2010
1890
|
|
|
2011
|
-
|
|
2012
|
-
a = n.attributes_dataset
|
|
2013
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
2014
|
-
a.sql.should == 'SELECT attributes.*, attribute_nodes.blah2 FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234))'
|
|
1891
|
+
@c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT attributes.*, attribute_nodes.blah2 FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234))'
|
|
2015
1892
|
end
|
|
2016
1893
|
|
|
2017
1894
|
it "should accept a block" do
|
|
@@ -2021,11 +1898,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2021
1898
|
|
|
2022
1899
|
n = @c2.new(:id => 1234)
|
|
2023
1900
|
n.xxx = 555
|
|
2024
|
-
|
|
2025
|
-
a.should be_a_kind_of(Array)
|
|
2026
|
-
a.size.should == 1
|
|
2027
|
-
a.first.should be_a_kind_of(@c1)
|
|
2028
|
-
MODEL_DB.sqls.first.should == 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234)) WHERE (xxx = 555)'
|
|
1901
|
+
n.attributes_dataset.sql.should == 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234)) WHERE (xxx = 555)'
|
|
2029
1902
|
end
|
|
2030
1903
|
|
|
2031
1904
|
it "should allow the :order option while accepting a block" do
|
|
@@ -2035,20 +1908,9 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2035
1908
|
|
|
2036
1909
|
n = @c2.new(:id => 1234)
|
|
2037
1910
|
n.xxx = 555
|
|
2038
|
-
|
|
2039
|
-
a.should be_a_kind_of(Array)
|
|
2040
|
-
a.size.should == 1
|
|
2041
|
-
a.first.should be_a_kind_of(@c1)
|
|
2042
|
-
MODEL_DB.sqls.first.should == 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234)) WHERE (xxx = 555) ORDER BY blah1, blah2'
|
|
1911
|
+
n.attributes_dataset.sql.should == 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234)) WHERE (xxx = 555) ORDER BY blah1, blah2'
|
|
2043
1912
|
end
|
|
2044
1913
|
|
|
2045
|
-
it "should have the block argument affect the _dataset method" do
|
|
2046
|
-
@c2.many_to_many :attributes, :class => @c1 do |ds|
|
|
2047
|
-
ds.filter(:xxx => 456)
|
|
2048
|
-
end
|
|
2049
|
-
@c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234)) WHERE (xxx = 456)'
|
|
2050
|
-
end
|
|
2051
|
-
|
|
2052
1914
|
it "should support a :dataset option that is used instead of the default" do
|
|
2053
1915
|
c1 = @c1
|
|
2054
1916
|
@c2.many_to_many :attributes, :class => @c1, :dataset=>proc{c1.join_table(:natural, :an).filter(:an__nodeid=>pk)}, :order=> :a, :limit=>10, :select=>nil do |ds|
|
|
@@ -2058,11 +1920,8 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2058
1920
|
n = @c2.new(:id => 1234)
|
|
2059
1921
|
n.xxx = 555
|
|
2060
1922
|
n.attributes_dataset.sql.should == 'SELECT * FROM attributes NATURAL JOIN an WHERE ((an.nodeid = 1234) AND (xxx = 555)) ORDER BY a LIMIT 10'
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
a.size.should == 1
|
|
2064
|
-
a.first.should be_a_kind_of(@c1)
|
|
2065
|
-
MODEL_DB.sqls.first.should == 'SELECT * FROM attributes NATURAL JOIN an WHERE ((an.nodeid = 1234) AND (xxx = 555)) ORDER BY a LIMIT 10'
|
|
1923
|
+
n.attributes.should == [@c1.load({})]
|
|
1924
|
+
MODEL_DB.sqls.should == ['SELECT * FROM attributes NATURAL JOIN an WHERE ((an.nodeid = 1234) AND (xxx = 555)) ORDER BY a LIMIT 10']
|
|
2066
1925
|
end
|
|
2067
1926
|
|
|
2068
1927
|
it "should support a :limit option" do
|
|
@@ -2077,15 +1936,32 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2077
1936
|
@c2.new(:id => 1234).attributes_dataset.opts[:eager].should == {:attributes=>nil}
|
|
2078
1937
|
end
|
|
2079
1938
|
|
|
1939
|
+
it "should handle an aliased join table" do
|
|
1940
|
+
@c2.many_to_many :attributes, :class => @c1, :join_table => :attribute2node___attributes_nodes
|
|
1941
|
+
n = @c2.load(:id => 1234)
|
|
1942
|
+
a = @c1.load(:id => 2345)
|
|
1943
|
+
n.attributes_dataset.sql.should == "SELECT attributes.* FROM attributes INNER JOIN attribute2node AS attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234))"
|
|
1944
|
+
a.should == n.add_attribute(a)
|
|
1945
|
+
a.should == n.remove_attribute(a)
|
|
1946
|
+
n.remove_all_attributes
|
|
1947
|
+
sqls = MODEL_DB.sqls
|
|
1948
|
+
['INSERT INTO attribute2node (node_id, attribute_id) VALUES (1234, 2345)',
|
|
1949
|
+
'INSERT INTO attribute2node (attribute_id, node_id) VALUES (2345, 1234)'].should(include(sqls.shift))
|
|
1950
|
+
["DELETE FROM attribute2node WHERE ((node_id = 1234) AND (attribute_id = 2345))",
|
|
1951
|
+
"DELETE FROM attribute2node WHERE ((attribute_id = 2345) AND (node_id = 1234))"].should(include(sqls.shift))
|
|
1952
|
+
sqls.should == ["DELETE FROM attribute2node WHERE (node_id = 1234)"]
|
|
1953
|
+
end
|
|
1954
|
+
|
|
2080
1955
|
it "should define an add_ method that works on existing records" do
|
|
2081
1956
|
@c2.many_to_many :attributes, :class => @c1
|
|
2082
1957
|
|
|
2083
1958
|
n = @c2.load(:id => 1234)
|
|
2084
1959
|
a = @c1.load(:id => 2345)
|
|
2085
|
-
a.should ==
|
|
1960
|
+
n.add_attribute(a).should == a
|
|
1961
|
+
sqls = MODEL_DB.sqls
|
|
2086
1962
|
['INSERT INTO attributes_nodes (node_id, attribute_id) VALUES (1234, 2345)',
|
|
2087
|
-
'INSERT INTO attributes_nodes (attribute_id, node_id) VALUES (2345, 1234)'
|
|
2088
|
-
|
|
1963
|
+
'INSERT INTO attributes_nodes (attribute_id, node_id) VALUES (2345, 1234)'].should(include(sqls.shift))
|
|
1964
|
+
sqls.should == []
|
|
2089
1965
|
end
|
|
2090
1966
|
|
|
2091
1967
|
it "should define an add_ method that works with a primary key" do
|
|
@@ -2093,21 +1969,25 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2093
1969
|
|
|
2094
1970
|
n = @c2.load(:id => 1234)
|
|
2095
1971
|
a = @c1.load(:id => 2345)
|
|
2096
|
-
|
|
1972
|
+
@c1.dataset._fetch = {:id=>2345}
|
|
1973
|
+
n.add_attribute(2345).should == a
|
|
1974
|
+
sqls = MODEL_DB.sqls
|
|
2097
1975
|
['INSERT INTO attributes_nodes (node_id, attribute_id) VALUES (1234, 2345)',
|
|
2098
|
-
'INSERT INTO attributes_nodes (attribute_id, node_id) VALUES (2345, 1234)'
|
|
2099
|
-
|
|
1976
|
+
'INSERT INTO attributes_nodes (attribute_id, node_id) VALUES (2345, 1234)'].should(include(sqls.pop))
|
|
1977
|
+
sqls.should == ["SELECT * FROM attributes WHERE id = 2345"]
|
|
2100
1978
|
end
|
|
2101
1979
|
|
|
2102
1980
|
it "should allow passing a hash to the add_ method which creates a new record" do
|
|
2103
1981
|
@c2.many_to_many :attributes, :class => @c1
|
|
2104
1982
|
|
|
2105
1983
|
n = @c2.load(:id => 1234)
|
|
2106
|
-
@c1.
|
|
2107
|
-
|
|
1984
|
+
@c1.dataset._fetch = @c1.instance_dataset._fetch = {:id=>1}
|
|
1985
|
+
n.add_attribute(:id => 1).should == @c1.load(:id => 1)
|
|
1986
|
+
sqls = MODEL_DB.sqls
|
|
2108
1987
|
['INSERT INTO attributes_nodes (node_id, attribute_id) VALUES (1234, 1)',
|
|
2109
1988
|
'INSERT INTO attributes_nodes (attribute_id, node_id) VALUES (1, 1234)'
|
|
2110
|
-
].should(include(
|
|
1989
|
+
].should(include(sqls.pop))
|
|
1990
|
+
sqls.should == ['INSERT INTO attributes (id) VALUES (1)', "SELECT * FROM attributes WHERE (id = 1) LIMIT 1"]
|
|
2111
1991
|
end
|
|
2112
1992
|
|
|
2113
1993
|
it "should define a remove_ method that works on existing records" do
|
|
@@ -2115,8 +1995,8 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2115
1995
|
|
|
2116
1996
|
n = @c2.new(:id => 1234)
|
|
2117
1997
|
a = @c1.new(:id => 2345)
|
|
2118
|
-
a.should ==
|
|
2119
|
-
MODEL_DB.sqls.
|
|
1998
|
+
n.remove_attribute(a).should == a
|
|
1999
|
+
MODEL_DB.sqls.should == ['DELETE FROM attributes_nodes WHERE ((node_id = 1234) AND (attribute_id = 2345))']
|
|
2120
2000
|
end
|
|
2121
2001
|
|
|
2122
2002
|
it "should raise an error in the add_ method if the passed associated object is not of the correct type" do
|
|
@@ -2127,13 +2007,8 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2127
2007
|
it "should accept a primary key for the remove_ method and remove an existing record" do
|
|
2128
2008
|
@c2.many_to_many :attributes, :class => @c1
|
|
2129
2009
|
n = @c2.new(:id => 1234)
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
db << sql
|
|
2133
|
-
yield({:id=>234})
|
|
2134
|
-
end
|
|
2135
|
-
MODEL_DB.reset
|
|
2136
|
-
@c1.load(:id => 234).should == n.remove_attribute(234)
|
|
2010
|
+
@c1.dataset._fetch = {:id=>234}
|
|
2011
|
+
n.remove_attribute(234).should == @c1.load(:id => 234)
|
|
2137
2012
|
MODEL_DB.sqls.should == ["SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234)) WHERE (attributes.id = 234) LIMIT 1",
|
|
2138
2013
|
"DELETE FROM attributes_nodes WHERE ((node_id = 1234) AND (attribute_id = 234))"]
|
|
2139
2014
|
end
|
|
@@ -2148,10 +2023,12 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2148
2023
|
|
|
2149
2024
|
n = @c2.load(:id => 1234).set(:xxx=>5)
|
|
2150
2025
|
a = @c1.load(:id => 2345).set(:yyy=>8)
|
|
2151
|
-
a.should ==
|
|
2026
|
+
n.add_attribute(a).should == a
|
|
2027
|
+
sqls = MODEL_DB.sqls
|
|
2152
2028
|
['INSERT INTO attributes_nodes (node_id, attribute_id) VALUES (5, 8)',
|
|
2153
2029
|
'INSERT INTO attributes_nodes (attribute_id, node_id) VALUES (8, 5)'
|
|
2154
|
-
].should(include(
|
|
2030
|
+
].should(include(sqls.pop))
|
|
2031
|
+
sqls.should == []
|
|
2155
2032
|
end
|
|
2156
2033
|
|
|
2157
2034
|
it "should have add_ method not add the same object to the cached association array if the object is already in the array" do
|
|
@@ -2166,11 +2043,13 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2166
2043
|
end
|
|
2167
2044
|
|
|
2168
2045
|
it "should have the add_ method respect composite keys" do
|
|
2169
|
-
@c2.many_to_many :attributes, :class => @c1, :left_key=>[:l1, :l2], :right_key=>[:r1, :r2], :left_primary_key=>[:id, :x], :right_primary_key=>[:id, :
|
|
2046
|
+
@c2.many_to_many :attributes, :class => @c1, :left_key=>[:l1, :l2], :right_key=>[:r1, :r2], :left_primary_key=>[:id, :x], :right_primary_key=>[:id, :z]
|
|
2170
2047
|
n = @c2.load(:id => 1234, :x=>5)
|
|
2171
|
-
a = @c1.load(:id => 2345, :
|
|
2048
|
+
a = @c1.load(:id => 2345, :z=>8)
|
|
2172
2049
|
a.should == n.add_attribute(a)
|
|
2173
|
-
|
|
2050
|
+
sqls = MODEL_DB.sqls
|
|
2051
|
+
m = /INSERT INTO attributes_nodes \((\w+), (\w+), (\w+), (\w+)\) VALUES \((\d+), (\d+), (\d+), (\d+)\)/.match(sqls.pop)
|
|
2052
|
+
sqls.should == []
|
|
2174
2053
|
m.should_not == nil
|
|
2175
2054
|
map = {'l1'=>1234, 'l2'=>5, 'r1'=>2345, 'r2'=>8}
|
|
2176
2055
|
%w[l1 l2 r1 r2].each do |x|
|
|
@@ -2186,11 +2065,16 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2186
2065
|
end
|
|
2187
2066
|
|
|
2188
2067
|
it "should have the add_ method respect composite keys" do
|
|
2189
|
-
@c2.many_to_many :attributes, :class => @c1, :left_key=>[:l1, :l2], :right_key=>[:r1, :r2], :left_primary_key=>[:id, :x], :right_primary_key=>[:id, :
|
|
2068
|
+
@c2.many_to_many :attributes, :class => @c1, :left_key=>[:l1, :l2], :right_key=>[:r1, :r2], :left_primary_key=>[:id, :x], :right_primary_key=>[:id, :z]
|
|
2069
|
+
@c1.set_primary_key [:id, :z]
|
|
2190
2070
|
n = @c2.load(:id => 1234, :x=>5)
|
|
2191
|
-
a = @c1.load(:id => 2345, :
|
|
2192
|
-
|
|
2193
|
-
|
|
2071
|
+
a = @c1.load(:id => 2345, :z=>8)
|
|
2072
|
+
@c1.dataset._fetch = {:id => 2345, :z=>8}
|
|
2073
|
+
n.add_attribute([2345, 8]).should == a
|
|
2074
|
+
sqls = MODEL_DB.sqls
|
|
2075
|
+
sqls.shift.should =~ /SELECT \* FROM attributes WHERE \(\((id|z) = (8|2345)\) AND \((id|z) = (8|2345)\)\) LIMIT 1/
|
|
2076
|
+
sqls.pop.should =~ /INSERT INTO attributes_nodes \([lr][12], [lr][12], [lr][12], [lr][12]\) VALUES \((1234|5|2345|8), (1234|5|2345|8), (1234|5|2345|8), (1234|5|2345|8)\)/
|
|
2077
|
+
sqls.should == []
|
|
2194
2078
|
end
|
|
2195
2079
|
|
|
2196
2080
|
it "should have the remove_ method respect the :left_primary_key and :right_primary_key options" do
|
|
@@ -2198,14 +2082,14 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2198
2082
|
|
|
2199
2083
|
n = @c2.new(:id => 1234, :xxx=>5)
|
|
2200
2084
|
a = @c1.new(:id => 2345, :yyy=>8)
|
|
2201
|
-
a.should ==
|
|
2202
|
-
MODEL_DB.sqls.
|
|
2085
|
+
n.remove_attribute(a).should == a
|
|
2086
|
+
MODEL_DB.sqls.should == ['DELETE FROM attributes_nodes WHERE ((node_id = 5) AND (attribute_id = 8))']
|
|
2203
2087
|
end
|
|
2204
2088
|
|
|
2205
2089
|
it "should have the remove_ method respect composite keys" do
|
|
2206
|
-
@c2.many_to_many :attributes, :class => @c1, :left_key=>[:l1, :l2], :right_key=>[:r1, :r2], :left_primary_key=>[:id, :x], :right_primary_key=>[:id, :
|
|
2090
|
+
@c2.many_to_many :attributes, :class => @c1, :left_key=>[:l1, :l2], :right_key=>[:r1, :r2], :left_primary_key=>[:id, :x], :right_primary_key=>[:id, :z]
|
|
2207
2091
|
n = @c2.load(:id => 1234, :x=>5)
|
|
2208
|
-
a = @c1.load(:id => 2345, :
|
|
2092
|
+
a = @c1.load(:id => 2345, :z=>8)
|
|
2209
2093
|
a.should == n.remove_attribute(a)
|
|
2210
2094
|
MODEL_DB.sqls.should == ["DELETE FROM attributes_nodes WHERE ((l1 = 1234) AND (l2 = 5) AND (r1 = 2345) AND (r2 = 8))"]
|
|
2211
2095
|
end
|
|
@@ -2214,17 +2098,12 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2214
2098
|
@c1.set_primary_key [:id, :y]
|
|
2215
2099
|
@c2.many_to_many :attributes, :class => @c1
|
|
2216
2100
|
n = @c2.new(:id => 1234)
|
|
2217
|
-
|
|
2218
|
-
def ds.fetch_rows(sql)
|
|
2219
|
-
db << sql
|
|
2220
|
-
yield({:id=>234, :y=>8})
|
|
2221
|
-
end
|
|
2222
|
-
MODEL_DB.reset
|
|
2101
|
+
@c1.dataset._fetch = {:id=>234, :y=>8}
|
|
2223
2102
|
@c1.load(:id => 234, :y=>8).should == n.remove_attribute([234, 8])
|
|
2103
|
+
sqls = MODEL_DB.sqls
|
|
2224
2104
|
["SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234)) WHERE ((attributes.id = 234) AND (attributes.y = 8)) LIMIT 1",
|
|
2225
|
-
"SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234)) WHERE ((attributes.y = 8) AND (attributes.id = 234)) LIMIT 1"].should include(
|
|
2226
|
-
|
|
2227
|
-
MODEL_DB.sqls.length.should == 2
|
|
2105
|
+
"SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234)) WHERE ((attributes.y = 8) AND (attributes.id = 234)) LIMIT 1"].should include(sqls.shift)
|
|
2106
|
+
sqls.should == ["DELETE FROM attributes_nodes WHERE ((node_id = 1234) AND (attribute_id = 234))"]
|
|
2228
2107
|
end
|
|
2229
2108
|
|
|
2230
2109
|
it "should raise an error if the model object doesn't have a valid primary key" do
|
|
@@ -2242,6 +2121,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2242
2121
|
n = @c1.new
|
|
2243
2122
|
a = @c2.load(:id=>123)
|
|
2244
2123
|
n.new?.should == true
|
|
2124
|
+
@c1.dataset._fetch = {:id=>1}
|
|
2245
2125
|
a.add_attribute(n)
|
|
2246
2126
|
n.new?.should == false
|
|
2247
2127
|
end
|
|
@@ -2250,7 +2130,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2250
2130
|
@c2.many_to_many :attributes, :class => @c1
|
|
2251
2131
|
n = @c1.new
|
|
2252
2132
|
a = @c2.load(:id=>123)
|
|
2253
|
-
def n.
|
|
2133
|
+
def n.validate() errors.add(:id, 'foo') end
|
|
2254
2134
|
proc{a.add_attribute(n)}.should raise_error(Sequel::ValidationFailed)
|
|
2255
2135
|
end
|
|
2256
2136
|
|
|
@@ -2259,7 +2139,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2259
2139
|
n = @c1.new
|
|
2260
2140
|
n.raise_on_save_failure = false
|
|
2261
2141
|
a = @c2.load(:id=>123)
|
|
2262
|
-
def n.
|
|
2142
|
+
def n.validate() errors.add(:id, 'foo') end
|
|
2263
2143
|
proc{a.add_attribute(n)}.should raise_error(Sequel::Error)
|
|
2264
2144
|
end
|
|
2265
2145
|
|
|
@@ -2267,7 +2147,8 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2267
2147
|
@c2.many_to_many :attributes, :class => @c1, :validate=>false
|
|
2268
2148
|
n = @c1.new
|
|
2269
2149
|
a = @c2.load(:id=>123)
|
|
2270
|
-
def n.
|
|
2150
|
+
def n.validate() errors.add(:id, 'foo') end
|
|
2151
|
+
@c1.dataset._fetch = {:id=>1}
|
|
2271
2152
|
a.add_attribute(n)
|
|
2272
2153
|
n.new?.should == false
|
|
2273
2154
|
end
|
|
@@ -2282,31 +2163,23 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2282
2163
|
it "should provide an array with all members of the association" do
|
|
2283
2164
|
@c2.many_to_many :attributes, :class => @c1
|
|
2284
2165
|
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
atts.should be_a_kind_of(Array)
|
|
2288
|
-
atts.size.should == 1
|
|
2289
|
-
atts.first.should be_a_kind_of(@c1)
|
|
2290
|
-
|
|
2291
|
-
MODEL_DB.sqls.first.should == 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234))'
|
|
2166
|
+
@c2.new(:id => 1234).attributes.should == [@c1.load({})]
|
|
2167
|
+
MODEL_DB.sqls.should == ['SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234))']
|
|
2292
2168
|
end
|
|
2293
2169
|
|
|
2294
2170
|
it "should set cached instance variable when accessed" do
|
|
2295
2171
|
@c2.many_to_many :attributes, :class => @c1
|
|
2296
2172
|
|
|
2297
2173
|
n = @c2.new(:id => 1234)
|
|
2298
|
-
MODEL_DB.reset
|
|
2299
2174
|
n.associations.include?(:attributes).should == false
|
|
2300
2175
|
atts = n.attributes
|
|
2301
2176
|
atts.should == n.associations[:attributes]
|
|
2302
|
-
MODEL_DB.sqls.length.should == 1
|
|
2303
2177
|
end
|
|
2304
2178
|
|
|
2305
2179
|
it "should use cached instance variable if available" do
|
|
2306
2180
|
@c2.many_to_many :attributes, :class => @c1
|
|
2307
2181
|
|
|
2308
2182
|
n = @c2.new(:id => 1234)
|
|
2309
|
-
MODEL_DB.reset
|
|
2310
2183
|
n.associations[:attributes] = 42
|
|
2311
2184
|
n.attributes.should == 42
|
|
2312
2185
|
MODEL_DB.sqls.should == []
|
|
@@ -2316,18 +2189,16 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2316
2189
|
@c2.many_to_many :attributes, :class => @c1
|
|
2317
2190
|
|
|
2318
2191
|
n = @c2.new(:id => 1234)
|
|
2319
|
-
MODEL_DB.reset
|
|
2320
2192
|
n.associations[:attributes] = 42
|
|
2321
2193
|
n.attributes(true).should_not == 42
|
|
2322
|
-
MODEL_DB.sqls.
|
|
2194
|
+
MODEL_DB.sqls.should == ["SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234))"]
|
|
2323
2195
|
end
|
|
2324
2196
|
|
|
2325
2197
|
it "should add item to cached instance variable if it exists when calling add_" do
|
|
2326
2198
|
@c2.many_to_many :attributes, :class => @c1
|
|
2327
2199
|
|
|
2328
2200
|
n = @c2.new(:id => 1234)
|
|
2329
|
-
att = @c1.
|
|
2330
|
-
MODEL_DB.reset
|
|
2201
|
+
att = @c1.load(:id => 345)
|
|
2331
2202
|
a = []
|
|
2332
2203
|
n.associations[:attributes] = a
|
|
2333
2204
|
n.add_attribute(att)
|
|
@@ -2339,7 +2210,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2339
2210
|
@c1.many_to_many :nodes, :class => @c2
|
|
2340
2211
|
|
|
2341
2212
|
n = @c2.new(:id => 1234)
|
|
2342
|
-
att = @c1.
|
|
2213
|
+
att = @c1.load(:id => 345)
|
|
2343
2214
|
att.associations[:nodes] = []
|
|
2344
2215
|
n.add_attribute(att)
|
|
2345
2216
|
att.nodes.should == [n]
|
|
@@ -2349,8 +2220,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2349
2220
|
@c2.many_to_many :attributes, :class => @c1
|
|
2350
2221
|
|
|
2351
2222
|
n = @c2.new(:id => 1234)
|
|
2352
|
-
att = @c1.
|
|
2353
|
-
MODEL_DB.reset
|
|
2223
|
+
att = @c1.load(:id => 345)
|
|
2354
2224
|
a = [att]
|
|
2355
2225
|
n.associations[:attributes] = a
|
|
2356
2226
|
n.remove_attribute(att)
|
|
@@ -2397,13 +2267,13 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2397
2267
|
it "should have an remove_all_ method that removes all associations" do
|
|
2398
2268
|
@c2.many_to_many :attributes, :class => @c1
|
|
2399
2269
|
@c2.new(:id => 1234).remove_all_attributes
|
|
2400
|
-
MODEL_DB.sqls.
|
|
2270
|
+
MODEL_DB.sqls.should == ['DELETE FROM attributes_nodes WHERE (node_id = 1234)']
|
|
2401
2271
|
end
|
|
2402
2272
|
|
|
2403
2273
|
it "should have the remove_all_ method respect the :left_primary_key option" do
|
|
2404
2274
|
@c2.many_to_many :attributes, :class => @c1, :left_primary_key=>:xxx
|
|
2405
2275
|
@c2.new(:id => 1234, :xxx=>5).remove_all_attributes
|
|
2406
|
-
MODEL_DB.sqls.
|
|
2276
|
+
MODEL_DB.sqls.should == ['DELETE FROM attributes_nodes WHERE (node_id = 5)']
|
|
2407
2277
|
end
|
|
2408
2278
|
|
|
2409
2279
|
it "should have the remove_all_ method respect composite keys" do
|
|
@@ -2421,10 +2291,9 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2421
2291
|
|
|
2422
2292
|
it "remove_all should return the array of previously associated items if the cached instance variable exists" do
|
|
2423
2293
|
@c2.many_to_many :attributes, :class => @c1
|
|
2424
|
-
attrib = @c1.
|
|
2425
|
-
node = @c2.
|
|
2426
|
-
|
|
2427
|
-
def d.fetch_rows(s); end
|
|
2294
|
+
attrib = @c1.load(:id=>3)
|
|
2295
|
+
node = @c2.load(:id => 1234)
|
|
2296
|
+
@c1.dataset._fetch = []
|
|
2428
2297
|
node.attributes.should == []
|
|
2429
2298
|
node.add_attribute(attrib)
|
|
2430
2299
|
node.associations[:attributes].should == [attrib]
|
|
@@ -2439,11 +2308,9 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2439
2308
|
it "remove_all should remove the current item from all reciprocal instance varaibles if it cached instance variable exists" do
|
|
2440
2309
|
@c2.many_to_many :attributes, :class => @c1
|
|
2441
2310
|
@c1.many_to_many :nodes, :class => @c2
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
def d.fetch_rows(s); end
|
|
2446
|
-
attrib = @c1.new(:id=>3)
|
|
2311
|
+
@c1.dataset._fetch = []
|
|
2312
|
+
@c2.dataset._fetch = []
|
|
2313
|
+
attrib = @c1.load(:id=>3)
|
|
2447
2314
|
node = @c2.new(:id => 1234)
|
|
2448
2315
|
node.attributes.should == []
|
|
2449
2316
|
attrib.nodes.should == []
|
|
@@ -2459,8 +2326,9 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2459
2326
|
o.add_attribute(@c1.load(:id=>44))
|
|
2460
2327
|
o.remove_attribute(@c1.load(:id=>45))
|
|
2461
2328
|
o.remove_all_attributes
|
|
2462
|
-
MODEL_DB.sqls
|
|
2463
|
-
|
|
2329
|
+
sqls = MODEL_DB.sqls
|
|
2330
|
+
sqls.shift =~ /INSERT INTO attributes_nodes \((node_id|attribute_id|x), (node_id|attribute_id|x), (node_id|attribute_id|x)\) VALUES \((1234|123|44), (1234|123|44), (1234|123|44)\)/
|
|
2331
|
+
sqls.should == ["DELETE FROM attributes_nodes WHERE ((x = 123) AND (node_id = 1234) AND (attribute_id = 45))",
|
|
2464
2332
|
"DELETE FROM attributes_nodes WHERE ((x = 123) AND (node_id = 1234))"]
|
|
2465
2333
|
end
|
|
2466
2334
|
|
|
@@ -2543,18 +2411,18 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2543
2411
|
h = []
|
|
2544
2412
|
@c2.many_to_many :attributes, :class => @c1, :before_add=>[proc{|x,y| h << x.pk; h << -y.pk}, :blah], :after_add=>proc{h << 3}, :before_remove=>:blah, :after_remove=>[:blahr]
|
|
2545
2413
|
@c2.class_eval do
|
|
2546
|
-
|
|
2414
|
+
self::Foo = h
|
|
2547
2415
|
def _add_attribute(v)
|
|
2548
|
-
|
|
2416
|
+
model::Foo << 4
|
|
2549
2417
|
end
|
|
2550
2418
|
def _remove_attribute(v)
|
|
2551
|
-
|
|
2419
|
+
model::Foo << 5
|
|
2552
2420
|
end
|
|
2553
2421
|
def blah(x)
|
|
2554
|
-
|
|
2422
|
+
model::Foo << x.pk
|
|
2555
2423
|
end
|
|
2556
2424
|
def blahr(x)
|
|
2557
|
-
|
|
2425
|
+
model::Foo << 6
|
|
2558
2426
|
end
|
|
2559
2427
|
end
|
|
2560
2428
|
p = @c2.load(:id=>10)
|
|
@@ -2570,17 +2438,12 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2570
2438
|
h = []
|
|
2571
2439
|
@c2.many_to_many :attributes, :class => @c1, :after_load=>[proc{|x,y| h << [x.pk, y.collect{|z|z.pk}]}, :al]
|
|
2572
2440
|
@c2.class_eval do
|
|
2573
|
-
|
|
2441
|
+
self::Foo = h
|
|
2574
2442
|
def al(v)
|
|
2575
|
-
v.each{|x|
|
|
2576
|
-
end
|
|
2577
|
-
end
|
|
2578
|
-
@c1.class_eval do
|
|
2579
|
-
def @dataset.fetch_rows(sql)
|
|
2580
|
-
yield({:id=>20})
|
|
2581
|
-
yield({:id=>30})
|
|
2443
|
+
v.each{|x| model::Foo << x.pk}
|
|
2582
2444
|
end
|
|
2583
2445
|
end
|
|
2446
|
+
@c1.dataset._fetch = [{:id=>20}, {:id=>30}]
|
|
2584
2447
|
p = @c2.load(:id=>10, :parent_id=>20)
|
|
2585
2448
|
attributes = p.attributes
|
|
2586
2449
|
h.should == [[10, [20, 30]], 20, 30]
|
|
@@ -2623,14 +2486,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2623
2486
|
|
|
2624
2487
|
it "should support a :uniq option that removes duplicates from the association" do
|
|
2625
2488
|
@c2.many_to_many :attributes, :class => @c1, :uniq=>true
|
|
2626
|
-
@c1.
|
|
2627
|
-
def @dataset.fetch_rows(sql)
|
|
2628
|
-
yield({:id=>20})
|
|
2629
|
-
yield({:id=>30})
|
|
2630
|
-
yield({:id=>20})
|
|
2631
|
-
yield({:id=>30})
|
|
2632
|
-
end
|
|
2633
|
-
end
|
|
2489
|
+
@c1.dataset._fetch = [{:id=>20}, {:id=>30}, {:id=>20}, {:id=>30}]
|
|
2634
2490
|
@c2.load(:id=>10, :parent_id=>20).attributes.should == [@c1.load(:id=>20), @c1.load(:id=>30)]
|
|
2635
2491
|
end
|
|
2636
2492
|
|
|
@@ -2651,76 +2507,733 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2651
2507
|
@c2.many_to_many :attributes, :class => @c1 do |ds|
|
|
2652
2508
|
ds.filter(:join_table_att=>3)
|
|
2653
2509
|
end
|
|
2654
|
-
@c1.dataset.
|
|
2655
|
-
def fetch_rows(sql, &block)
|
|
2656
|
-
db.sqls << sql
|
|
2657
|
-
yield(:id=>2)
|
|
2658
|
-
end
|
|
2659
|
-
end
|
|
2510
|
+
@c1.dataset._fetch = {:id=>2}
|
|
2660
2511
|
@c2.load(:id=>1).remove_attribute(2)
|
|
2661
2512
|
MODEL_DB.sqls.should == ["SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1)) WHERE ((join_table_att = 3) AND (attributes.id = 2)) LIMIT 1",
|
|
2662
2513
|
"DELETE FROM attributes_nodes WHERE ((node_id = 1) AND (attribute_id = 2))"]
|
|
2663
2514
|
end
|
|
2664
2515
|
end
|
|
2665
2516
|
|
|
2666
|
-
describe
|
|
2517
|
+
describe "Filtering by associations" do
|
|
2667
2518
|
before do
|
|
2668
|
-
|
|
2669
|
-
@
|
|
2670
|
-
|
|
2671
|
-
|
|
2519
|
+
@Album = Class.new(Sequel::Model(:albums))
|
|
2520
|
+
artist = @Artist = Class.new(Sequel::Model(:artists))
|
|
2521
|
+
tag = @Tag = Class.new(Sequel::Model(:tags))
|
|
2522
|
+
track = @Track = Class.new(Sequel::Model(:tracks))
|
|
2523
|
+
album_info = @AlbumInfo = Class.new(Sequel::Model(:album_infos))
|
|
2524
|
+
@Artist.columns :id, :id1, :id2
|
|
2525
|
+
@Tag.columns :id, :tid1, :tid2
|
|
2526
|
+
@Track.columns :id, :album_id, :album_id1, :album_id2
|
|
2527
|
+
@AlbumInfo.columns :id, :album_id, :album_id1, :album_id2
|
|
2528
|
+
@Album.class_eval do
|
|
2529
|
+
columns :id, :id1, :id2, :artist_id, :artist_id1, :artist_id2
|
|
2530
|
+
many_to_one :artist, :class=>artist
|
|
2531
|
+
one_to_many :tracks, :class=>track, :key=>:album_id
|
|
2532
|
+
one_to_one :album_info, :class=>album_info, :key=>:album_id
|
|
2533
|
+
many_to_many :tags, :class=>tag, :left_key=>:album_id, :join_table=>:albums_tags
|
|
2534
|
+
|
|
2535
|
+
many_to_one :cartist, :class=>artist, :key=>[:artist_id1, :artist_id2], :primary_key=>[:id1, :id2]
|
|
2536
|
+
one_to_many :ctracks, :class=>track, :key=>[:album_id1, :album_id2], :primary_key=>[:id1, :id2]
|
|
2537
|
+
one_to_one :calbum_info, :class=>album_info, :key=>[:album_id1, :album_id2], :primary_key=>[:id1, :id2]
|
|
2538
|
+
many_to_many :ctags, :class=>tag, :left_key=>[:album_id1, :album_id2], :left_primary_key=>[:id1, :id2], :right_key=>[:tag_id1, :tag_id2], :right_primary_key=>[:tid1, :tid2], :join_table=>:albums_tags
|
|
2672
2539
|
end
|
|
2673
2540
|
end
|
|
2541
|
+
|
|
2542
|
+
it "should be able to filter on many_to_one associations" do
|
|
2543
|
+
@Album.filter(:artist=>@Artist.load(:id=>3)).sql.should == 'SELECT * FROM albums WHERE (albums.artist_id = 3)'
|
|
2544
|
+
end
|
|
2545
|
+
|
|
2546
|
+
it "should be able to filter on one_to_many associations" do
|
|
2547
|
+
@Album.filter(:tracks=>@Track.load(:album_id=>3)).sql.should == 'SELECT * FROM albums WHERE (albums.id = 3)'
|
|
2548
|
+
end
|
|
2549
|
+
|
|
2550
|
+
it "should be able to filter on one_to_one associations" do
|
|
2551
|
+
@Album.filter(:album_info=>@AlbumInfo.load(:album_id=>3)).sql.should == 'SELECT * FROM albums WHERE (albums.id = 3)'
|
|
2552
|
+
end
|
|
2553
|
+
|
|
2554
|
+
it "should be able to filter on many_to_many associations" do
|
|
2555
|
+
@Album.filter(:tags=>@Tag.load(:id=>3)).sql.should == 'SELECT * FROM albums WHERE (albums.id IN (SELECT albums_tags.album_id FROM albums_tags WHERE ((albums_tags.tag_id = 3) AND (albums_tags.album_id IS NOT NULL))))'
|
|
2556
|
+
end
|
|
2557
|
+
|
|
2558
|
+
it "should be able to filter on many_to_one associations with composite keys" do
|
|
2559
|
+
@Album.filter(:cartist=>@Artist.load(:id1=>3, :id2=>4)).sql.should == 'SELECT * FROM albums WHERE ((albums.artist_id1 = 3) AND (albums.artist_id2 = 4))'
|
|
2560
|
+
end
|
|
2561
|
+
|
|
2562
|
+
it "should be able to filter on one_to_many associations with composite keys" do
|
|
2563
|
+
@Album.filter(:ctracks=>@Track.load(:album_id1=>3, :album_id2=>4)).sql.should == 'SELECT * FROM albums WHERE ((albums.id1 = 3) AND (albums.id2 = 4))'
|
|
2564
|
+
end
|
|
2565
|
+
|
|
2566
|
+
it "should be able to filter on one_to_one associations with composite keys" do
|
|
2567
|
+
@Album.filter(:calbum_info=>@AlbumInfo.load(:album_id1=>3, :album_id2=>4)).sql.should == 'SELECT * FROM albums WHERE ((albums.id1 = 3) AND (albums.id2 = 4))'
|
|
2568
|
+
end
|
|
2569
|
+
|
|
2570
|
+
it "should be able to filter on many_to_many associations with composite keys" do
|
|
2571
|
+
@Album.filter(:ctags=>@Tag.load(:tid1=>3, :tid2=>4)).sql.should == 'SELECT * FROM albums WHERE ((albums.id1, albums.id2) IN (SELECT albums_tags.album_id1, albums_tags.album_id2 FROM albums_tags WHERE ((albums_tags.tag_id1 = 3) AND (albums_tags.tag_id2 = 4) AND (albums_tags.album_id1 IS NOT NULL) AND (albums_tags.album_id2 IS NOT NULL))))'
|
|
2572
|
+
end
|
|
2573
|
+
|
|
2574
|
+
it "should work inside a complex filter" do
|
|
2575
|
+
artist = @Artist.load(:id=>3)
|
|
2576
|
+
@Album.filter{foo & {:artist=>artist}}.sql.should == 'SELECT * FROM albums WHERE (foo AND (albums.artist_id = 3))'
|
|
2577
|
+
track = @Track.load(:album_id=>4)
|
|
2578
|
+
@Album.filter{foo & [[:artist, artist], [:tracks, track]]}.sql.should == 'SELECT * FROM albums WHERE (foo AND (albums.artist_id = 3) AND (albums.id = 4))'
|
|
2579
|
+
end
|
|
2580
|
+
|
|
2581
|
+
it "should raise for an invalid association name" do
|
|
2582
|
+
proc{@Album.filter(:foo=>@Artist.load(:id=>3)).sql}.should raise_error(Sequel::Error)
|
|
2583
|
+
end
|
|
2584
|
+
|
|
2585
|
+
it "should raise for an invalid association type" do
|
|
2586
|
+
@Album.many_to_many :iatags, :clone=>:tags
|
|
2587
|
+
@Album.association_reflection(:iatags)[:type] = :foo
|
|
2588
|
+
proc{@Album.filter(:iatags=>@Tag.load(:id=>3)).sql}.should raise_error(Sequel::Error)
|
|
2589
|
+
end
|
|
2590
|
+
|
|
2591
|
+
it "should raise for an invalid associated object class " do
|
|
2592
|
+
proc{@Album.filter(:tags=>@Artist.load(:id=>3)).sql}.should raise_error(Sequel::Error)
|
|
2593
|
+
end
|
|
2594
|
+
|
|
2595
|
+
it "should raise for an invalid associated object class when multiple objects are used" do
|
|
2596
|
+
proc{@Album.filter(:tags=>[@Tag.load(:id=>3), @Artist.load(:id=>3)]).sql}.should raise_error(Sequel::Error)
|
|
2597
|
+
end
|
|
2598
|
+
|
|
2599
|
+
it "should correctly handle case when a multiple value association is used" do
|
|
2600
|
+
proc{@Album.filter(:tags=>[@Tag.load(:id=>3), @Artist.load(:id=>3)]).sql}.should raise_error(Sequel::Error)
|
|
2601
|
+
end
|
|
2602
|
+
|
|
2603
|
+
it "should not affect non-association IN/NOT IN filtering with an empty array" do
|
|
2604
|
+
@Album.filter(:tag_id=>[]).sql.should == 'SELECT * FROM albums WHERE (tag_id != tag_id)'
|
|
2605
|
+
@Album.exclude(:tag_id=>[]).sql.should == 'SELECT * FROM albums WHERE (tag_id = tag_id)'
|
|
2606
|
+
end
|
|
2607
|
+
|
|
2608
|
+
it "should work correctly in subclasses" do
|
|
2609
|
+
c = Class.new(@Album)
|
|
2610
|
+
c.many_to_one :sartist, :class=>@Artist
|
|
2611
|
+
c.filter(:sartist=>@Artist.load(:id=>3)).sql.should == 'SELECT * FROM albums WHERE (albums.sartist_id = 3)'
|
|
2612
|
+
end
|
|
2613
|
+
|
|
2614
|
+
it "should be able to exclude on many_to_one associations" do
|
|
2615
|
+
@Album.exclude(:artist=>@Artist.load(:id=>3)).sql.should == 'SELECT * FROM albums WHERE ((albums.artist_id != 3) OR (albums.artist_id IS NULL))'
|
|
2616
|
+
end
|
|
2617
|
+
|
|
2618
|
+
it "should be able to exclude on one_to_many associations" do
|
|
2619
|
+
@Album.exclude(:tracks=>@Track.load(:album_id=>3)).sql.should == 'SELECT * FROM albums WHERE ((albums.id != 3) OR (albums.id IS NULL))'
|
|
2620
|
+
end
|
|
2621
|
+
|
|
2622
|
+
it "should be able to exclude on one_to_one associations" do
|
|
2623
|
+
@Album.exclude(:album_info=>@AlbumInfo.load(:album_id=>3)).sql.should == 'SELECT * FROM albums WHERE ((albums.id != 3) OR (albums.id IS NULL))'
|
|
2624
|
+
end
|
|
2625
|
+
|
|
2626
|
+
it "should be able to exclude on many_to_many associations" do
|
|
2627
|
+
@Album.exclude(:tags=>@Tag.load(:id=>3)).sql.should == 'SELECT * FROM albums WHERE ((albums.id NOT IN (SELECT albums_tags.album_id FROM albums_tags WHERE ((albums_tags.tag_id = 3) AND (albums_tags.album_id IS NOT NULL)))) OR (albums.id IS NULL))'
|
|
2628
|
+
end
|
|
2629
|
+
|
|
2630
|
+
it "should be able to exclude on many_to_one associations with composite keys" do
|
|
2631
|
+
@Album.exclude(:cartist=>@Artist.load(:id1=>3, :id2=>4)).sql.should == 'SELECT * FROM albums WHERE ((albums.artist_id1 != 3) OR (albums.artist_id2 != 4) OR (albums.artist_id1 IS NULL) OR (albums.artist_id2 IS NULL))'
|
|
2632
|
+
end
|
|
2633
|
+
|
|
2634
|
+
it "should be able to exclude on one_to_many associations with composite keys" do
|
|
2635
|
+
@Album.exclude(:ctracks=>@Track.load(:album_id1=>3, :album_id2=>4)).sql.should == 'SELECT * FROM albums WHERE ((albums.id1 != 3) OR (albums.id2 != 4) OR (albums.id1 IS NULL) OR (albums.id2 IS NULL))'
|
|
2636
|
+
end
|
|
2637
|
+
|
|
2638
|
+
it "should be able to exclude on one_to_one associations with composite keys" do
|
|
2639
|
+
@Album.exclude(:calbum_info=>@AlbumInfo.load(:album_id1=>3, :album_id2=>4)).sql.should == 'SELECT * FROM albums WHERE ((albums.id1 != 3) OR (albums.id2 != 4) OR (albums.id1 IS NULL) OR (albums.id2 IS NULL))'
|
|
2640
|
+
end
|
|
2641
|
+
|
|
2642
|
+
it "should be able to exclude on many_to_many associations with composite keys" do
|
|
2643
|
+
@Album.exclude(:ctags=>@Tag.load(:tid1=>3, :tid2=>4)).sql.should == 'SELECT * FROM albums WHERE (((albums.id1, albums.id2) NOT IN (SELECT albums_tags.album_id1, albums_tags.album_id2 FROM albums_tags WHERE ((albums_tags.tag_id1 = 3) AND (albums_tags.tag_id2 = 4) AND (albums_tags.album_id1 IS NOT NULL) AND (albums_tags.album_id2 IS NOT NULL)))) OR (albums.id1 IS NULL) OR (albums.id2 IS NULL))'
|
|
2644
|
+
end
|
|
2645
|
+
|
|
2646
|
+
it "should be able to filter on multiple many_to_one associations" do
|
|
2647
|
+
@Album.filter(:artist=>[@Artist.load(:id=>3), @Artist.load(:id=>4)]).sql.should == 'SELECT * FROM albums WHERE (albums.artist_id IN (3, 4))'
|
|
2648
|
+
end
|
|
2649
|
+
|
|
2650
|
+
it "should be able to filter on multiple one_to_many associations" do
|
|
2651
|
+
@Album.filter(:tracks=>[@Track.load(:album_id=>3), @Track.load(:album_id=>4)]).sql.should == 'SELECT * FROM albums WHERE (albums.id IN (3, 4))'
|
|
2652
|
+
end
|
|
2653
|
+
|
|
2654
|
+
it "should be able to filter on multiple one_to_one associations" do
|
|
2655
|
+
@Album.filter(:album_info=>[@AlbumInfo.load(:album_id=>3), @AlbumInfo.load(:album_id=>4)]).sql.should == 'SELECT * FROM albums WHERE (albums.id IN (3, 4))'
|
|
2656
|
+
end
|
|
2657
|
+
|
|
2658
|
+
it "should be able to filter on multiple many_to_many associations" do
|
|
2659
|
+
@Album.filter(:tags=>[@Tag.load(:id=>3), @Tag.load(:id=>4)]).sql.should == 'SELECT * FROM albums WHERE (albums.id IN (SELECT albums_tags.album_id FROM albums_tags WHERE ((albums_tags.tag_id IN (3, 4)) AND (albums_tags.album_id IS NOT NULL))))'
|
|
2660
|
+
end
|
|
2661
|
+
|
|
2662
|
+
it "should be able to filter on multiple many_to_one associations with composite keys" do
|
|
2663
|
+
@Album.filter(:cartist=>[@Artist.load(:id1=>3, :id2=>4), @Artist.load(:id1=>5, :id2=>6)]).sql.should == 'SELECT * FROM albums WHERE ((albums.artist_id1, albums.artist_id2) IN ((3, 4), (5, 6)))'
|
|
2664
|
+
end
|
|
2665
|
+
|
|
2666
|
+
it "should be able to filter on multiple one_to_many associations with composite keys" do
|
|
2667
|
+
@Album.filter(:ctracks=>[@Track.load(:album_id1=>3, :album_id2=>4), @Track.load(:album_id1=>5, :album_id2=>6)]).sql.should == 'SELECT * FROM albums WHERE ((albums.id1, albums.id2) IN ((3, 4), (5, 6)))'
|
|
2668
|
+
end
|
|
2669
|
+
|
|
2670
|
+
it "should be able to filter on multiple one_to_one associations with composite keys" do
|
|
2671
|
+
@Album.filter(:calbum_info=>[@AlbumInfo.load(:album_id1=>3, :album_id2=>4), @AlbumInfo.load(:album_id1=>5, :album_id2=>6)]).sql.should == 'SELECT * FROM albums WHERE ((albums.id1, albums.id2) IN ((3, 4), (5, 6)))'
|
|
2672
|
+
end
|
|
2673
|
+
|
|
2674
|
+
it "should be able to filter on multiple many_to_many associations with composite keys" do
|
|
2675
|
+
@Album.filter(:ctags=>[@Tag.load(:tid1=>3, :tid2=>4), @Tag.load(:tid1=>5, :tid2=>6)]).sql.should == 'SELECT * FROM albums WHERE ((albums.id1, albums.id2) IN (SELECT albums_tags.album_id1, albums_tags.album_id2 FROM albums_tags WHERE (((albums_tags.tag_id1, albums_tags.tag_id2) IN ((3, 4), (5, 6))) AND (albums_tags.album_id1 IS NOT NULL) AND (albums_tags.album_id2 IS NOT NULL))))'
|
|
2676
|
+
end
|
|
2677
|
+
|
|
2678
|
+
it "should be able to exclude on multiple many_to_one associations" do
|
|
2679
|
+
@Album.exclude(:artist=>[@Artist.load(:id=>3), @Artist.load(:id=>4)]).sql.should == 'SELECT * FROM albums WHERE ((albums.artist_id NOT IN (3, 4)) OR (albums.artist_id IS NULL))'
|
|
2680
|
+
end
|
|
2681
|
+
|
|
2682
|
+
it "should be able to exclude on multiple one_to_many associations" do
|
|
2683
|
+
@Album.exclude(:tracks=>[@Track.load(:album_id=>3), @Track.load(:album_id=>4)]).sql.should == 'SELECT * FROM albums WHERE ((albums.id NOT IN (3, 4)) OR (albums.id IS NULL))'
|
|
2684
|
+
end
|
|
2685
|
+
|
|
2686
|
+
it "should be able to exclude on multiple one_to_one associations" do
|
|
2687
|
+
@Album.exclude(:album_info=>[@AlbumInfo.load(:album_id=>3), @AlbumInfo.load(:album_id=>4)]).sql.should == 'SELECT * FROM albums WHERE ((albums.id NOT IN (3, 4)) OR (albums.id IS NULL))'
|
|
2688
|
+
end
|
|
2689
|
+
|
|
2690
|
+
it "should be able to exclude on multiple many_to_many associations" do
|
|
2691
|
+
@Album.exclude(:tags=>[@Tag.load(:id=>3), @Tag.load(:id=>4)]).sql.should == 'SELECT * FROM albums WHERE ((albums.id NOT IN (SELECT albums_tags.album_id FROM albums_tags WHERE ((albums_tags.tag_id IN (3, 4)) AND (albums_tags.album_id IS NOT NULL)))) OR (albums.id IS NULL))'
|
|
2692
|
+
end
|
|
2693
|
+
|
|
2694
|
+
it "should be able to exclude on multiple many_to_one associations with composite keys" do
|
|
2695
|
+
@Album.exclude(:cartist=>[@Artist.load(:id1=>3, :id2=>4), @Artist.load(:id1=>5, :id2=>6)]).sql.should == 'SELECT * FROM albums WHERE (((albums.artist_id1, albums.artist_id2) NOT IN ((3, 4), (5, 6))) OR (albums.artist_id1 IS NULL) OR (albums.artist_id2 IS NULL))'
|
|
2696
|
+
end
|
|
2697
|
+
|
|
2698
|
+
it "should be able to exclude on multiple one_to_many associations with composite keys" do
|
|
2699
|
+
@Album.exclude(:ctracks=>[@Track.load(:album_id1=>3, :album_id2=>4), @Track.load(:album_id1=>5, :album_id2=>6)]).sql.should == 'SELECT * FROM albums WHERE (((albums.id1, albums.id2) NOT IN ((3, 4), (5, 6))) OR (albums.id1 IS NULL) OR (albums.id2 IS NULL))'
|
|
2700
|
+
end
|
|
2701
|
+
|
|
2702
|
+
it "should be able to exclude on multiple one_to_one associations with composite keys" do
|
|
2703
|
+
@Album.exclude(:calbum_info=>[@AlbumInfo.load(:album_id1=>3, :album_id2=>4), @AlbumInfo.load(:album_id1=>5, :album_id2=>6)]).sql.should == 'SELECT * FROM albums WHERE (((albums.id1, albums.id2) NOT IN ((3, 4), (5, 6))) OR (albums.id1 IS NULL) OR (albums.id2 IS NULL))'
|
|
2704
|
+
end
|
|
2705
|
+
|
|
2706
|
+
it "should be able to exclude on multiple many_to_many associations with composite keys" do
|
|
2707
|
+
@Album.exclude(:ctags=>[@Tag.load(:tid1=>3, :tid2=>4), @Tag.load(:tid1=>5, :tid2=>6)]).sql.should == 'SELECT * FROM albums WHERE (((albums.id1, albums.id2) NOT IN (SELECT albums_tags.album_id1, albums_tags.album_id2 FROM albums_tags WHERE (((albums_tags.tag_id1, albums_tags.tag_id2) IN ((3, 4), (5, 6))) AND (albums_tags.album_id1 IS NOT NULL) AND (albums_tags.album_id2 IS NOT NULL)))) OR (albums.id1 IS NULL) OR (albums.id2 IS NULL))'
|
|
2708
|
+
end
|
|
2709
|
+
|
|
2710
|
+
it "should be able to handle NULL values when filtering many_to_one associations" do
|
|
2711
|
+
@Album.filter(:artist=>@Artist.new).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2712
|
+
end
|
|
2713
|
+
|
|
2714
|
+
it "should be able to handle NULL values when filtering one_to_many associations" do
|
|
2715
|
+
@Album.filter(:tracks=>@Track.new).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2716
|
+
end
|
|
2717
|
+
|
|
2718
|
+
it "should be able to handle NULL values when filtering one_to_one associations" do
|
|
2719
|
+
@Album.filter(:album_info=>@AlbumInfo.new).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2720
|
+
end
|
|
2721
|
+
|
|
2722
|
+
it "should be able to handle NULL values when filtering many_to_many associations" do
|
|
2723
|
+
@Album.filter(:tags=>@Tag.new).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2724
|
+
end
|
|
2725
|
+
|
|
2726
|
+
it "should be able to handle filtering with NULL values for many_to_one associations with composite keys" do
|
|
2727
|
+
@Album.filter(:cartist=>@Artist.load(:id2=>4)).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2728
|
+
@Album.filter(:cartist=>@Artist.load(:id1=>3)).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2729
|
+
@Album.filter(:cartist=>@Artist.new).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2730
|
+
end
|
|
2731
|
+
|
|
2732
|
+
it "should be able to filter with NULL values for one_to_many associations with composite keys" do
|
|
2733
|
+
@Album.filter(:ctracks=>@Track.load(:album_id2=>4)).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2734
|
+
@Album.filter(:ctracks=>@Track.load(:album_id1=>3)).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2735
|
+
@Album.filter(:ctracks=>@Track.new).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2736
|
+
end
|
|
2737
|
+
|
|
2738
|
+
it "should be able to filter with NULL values for one_to_one associations with composite keys" do
|
|
2739
|
+
@Album.filter(:calbum_info=>@AlbumInfo.load(:album_id2=>4)).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2740
|
+
@Album.filter(:calbum_info=>@AlbumInfo.load(:album_id1=>3)).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2741
|
+
@Album.filter(:calbum_info=>@AlbumInfo.new).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2742
|
+
end
|
|
2743
|
+
|
|
2744
|
+
it "should be able to filter with NULL values for many_to_many associations with composite keys" do
|
|
2745
|
+
@Album.filter(:ctags=>@Tag.load(:tid1=>3)).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2746
|
+
@Album.filter(:ctags=>@Tag.load(:tid2=>4)).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2747
|
+
@Album.filter(:ctags=>@Tag.new).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2748
|
+
end
|
|
2749
|
+
|
|
2750
|
+
it "should be able to handle NULL values when excluding many_to_one associations" do
|
|
2751
|
+
@Album.exclude(:artist=>@Artist.new).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
2752
|
+
end
|
|
2753
|
+
|
|
2754
|
+
it "should be able to handle NULL values when excluding one_to_many associations" do
|
|
2755
|
+
@Album.exclude(:tracks=>@Track.new).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
2756
|
+
end
|
|
2757
|
+
|
|
2758
|
+
it "should be able to handle NULL values when excluding one_to_one associations" do
|
|
2759
|
+
@Album.exclude(:album_info=>@AlbumInfo.new).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
2760
|
+
end
|
|
2761
|
+
|
|
2762
|
+
it "should be able to handle NULL values when excluding many_to_many associations" do
|
|
2763
|
+
@Album.exclude(:tags=>@Tag.new).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
2764
|
+
end
|
|
2765
|
+
|
|
2766
|
+
it "should be able to handle excluding with NULL values for many_to_one associations with composite keys" do
|
|
2767
|
+
@Album.exclude(:cartist=>@Artist.load(:id2=>4)).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
2768
|
+
@Album.exclude(:cartist=>@Artist.load(:id1=>3)).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
2769
|
+
@Album.exclude(:cartist=>@Artist.new).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
2770
|
+
end
|
|
2771
|
+
|
|
2772
|
+
it "should be able to excluding with NULL values for one_to_many associations with composite keys" do
|
|
2773
|
+
@Album.exclude(:ctracks=>@Track.load(:album_id2=>4)).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
2774
|
+
@Album.exclude(:ctracks=>@Track.load(:album_id1=>3)).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
2775
|
+
@Album.exclude(:ctracks=>@Track.new).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
2776
|
+
end
|
|
2777
|
+
|
|
2778
|
+
it "should be able to excluding with NULL values for one_to_one associations with composite keys" do
|
|
2779
|
+
@Album.exclude(:calbum_info=>@AlbumInfo.load(:album_id2=>4)).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
2780
|
+
@Album.exclude(:calbum_info=>@AlbumInfo.load(:album_id1=>3)).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
2781
|
+
@Album.exclude(:calbum_info=>@AlbumInfo.new).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
2782
|
+
end
|
|
2783
|
+
|
|
2784
|
+
it "should be able to excluding with NULL values for many_to_many associations with composite keys" do
|
|
2785
|
+
@Album.exclude(:ctags=>@Tag.load(:tid1=>3)).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
2786
|
+
@Album.exclude(:ctags=>@Tag.load(:tid2=>4)).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
2787
|
+
@Album.exclude(:ctags=>@Tag.new).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
2788
|
+
end
|
|
2789
|
+
|
|
2790
|
+
it "should be able to handle NULL values when filtering multiple many_to_one associations" do
|
|
2791
|
+
@Album.filter(:artist=>[@Artist.load(:id=>3), @Artist.new]).sql.should == 'SELECT * FROM albums WHERE (albums.artist_id IN (3))'
|
|
2792
|
+
@Album.filter(:artist=>[@Artist.new, @Artist.new]).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2793
|
+
end
|
|
2794
|
+
|
|
2795
|
+
it "should be able to handle NULL values when filtering multiple one_to_many associations" do
|
|
2796
|
+
@Album.filter(:tracks=>[@Track.load(:album_id=>3), @Track.new]).sql.should == 'SELECT * FROM albums WHERE (albums.id IN (3))'
|
|
2797
|
+
@Album.filter(:tracks=>[@Track.new, @Track.new]).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2798
|
+
end
|
|
2799
|
+
|
|
2800
|
+
it "should be able to handle NULL values when filtering multiple one_to_one associations" do
|
|
2801
|
+
@Album.filter(:album_info=>[@AlbumInfo.load(:album_id=>3), @AlbumInfo.new]).sql.should == 'SELECT * FROM albums WHERE (albums.id IN (3))'
|
|
2802
|
+
@Album.filter(:album_info=>[@AlbumInfo.new, @AlbumInfo.new]).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2803
|
+
end
|
|
2804
|
+
|
|
2805
|
+
it "should be able to handle NULL values when filtering multiple many_to_many associations" do
|
|
2806
|
+
@Album.filter(:tags=>[@Tag.load(:id=>3), @Tag.new]).sql.should == 'SELECT * FROM albums WHERE (albums.id IN (SELECT albums_tags.album_id FROM albums_tags WHERE ((albums_tags.tag_id IN (3)) AND (albums_tags.album_id IS NOT NULL))))'
|
|
2807
|
+
@Album.filter(:tags=>[@Tag.new, @Tag.new]).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2808
|
+
end
|
|
2809
|
+
|
|
2810
|
+
it "should be able to handle NULL values when filtering multiple many_to_one associations with composite keys" do
|
|
2811
|
+
@Album.filter(:cartist=>[@Artist.load(:id1=>3, :id2=>4), @Artist.load(:id1=>3)]).sql.should == 'SELECT * FROM albums WHERE ((albums.artist_id1, albums.artist_id2) IN ((3, 4)))'
|
|
2812
|
+
@Album.filter(:cartist=>[@Artist.load(:id1=>3, :id2=>4), @Artist.new]).sql.should == 'SELECT * FROM albums WHERE ((albums.artist_id1, albums.artist_id2) IN ((3, 4)))'
|
|
2813
|
+
end
|
|
2814
|
+
|
|
2815
|
+
it "should be able handle NULL values when filtering multiple one_to_many associations with composite keys" do
|
|
2816
|
+
@Album.filter(:ctracks=>[@Track.load(:album_id1=>3, :album_id2=>4), @Track.load(:album_id1=>3)]).sql.should == 'SELECT * FROM albums WHERE ((albums.id1, albums.id2) IN ((3, 4)))'
|
|
2817
|
+
@Album.filter(:ctracks=>[@Track.load(:album_id1=>3, :album_id2=>4), @Track.new]).sql.should == 'SELECT * FROM albums WHERE ((albums.id1, albums.id2) IN ((3, 4)))'
|
|
2818
|
+
end
|
|
2819
|
+
|
|
2820
|
+
it "should be able to handle NULL values when filtering multiple one_to_one associations with composite keys" do
|
|
2821
|
+
@Album.filter(:calbum_info=>[@AlbumInfo.load(:album_id1=>3, :album_id2=>4), @AlbumInfo.load(:album_id1=>5)]).sql.should == 'SELECT * FROM albums WHERE ((albums.id1, albums.id2) IN ((3, 4)))'
|
|
2822
|
+
@Album.filter(:calbum_info=>[@AlbumInfo.load(:album_id1=>3, :album_id2=>4), @AlbumInfo.new]).sql.should == 'SELECT * FROM albums WHERE ((albums.id1, albums.id2) IN ((3, 4)))'
|
|
2823
|
+
end
|
|
2824
|
+
|
|
2825
|
+
it "should be able to handle NULL values when filtering multiple many_to_many associations with composite keys" do
|
|
2826
|
+
@Album.filter(:ctags=>[@Tag.load(:tid1=>3, :tid2=>4), @Tag.load(:tid1=>5)]).sql.should == 'SELECT * FROM albums WHERE ((albums.id1, albums.id2) IN (SELECT albums_tags.album_id1, albums_tags.album_id2 FROM albums_tags WHERE (((albums_tags.tag_id1, albums_tags.tag_id2) IN ((3, 4))) AND (albums_tags.album_id1 IS NOT NULL) AND (albums_tags.album_id2 IS NOT NULL))))'
|
|
2827
|
+
@Album.filter(:ctags=>[@Tag.load(:tid1=>3, :tid2=>4), @Tag.new]).sql.should == 'SELECT * FROM albums WHERE ((albums.id1, albums.id2) IN (SELECT albums_tags.album_id1, albums_tags.album_id2 FROM albums_tags WHERE (((albums_tags.tag_id1, albums_tags.tag_id2) IN ((3, 4))) AND (albums_tags.album_id1 IS NOT NULL) AND (albums_tags.album_id2 IS NOT NULL))))'
|
|
2828
|
+
end
|
|
2829
|
+
|
|
2830
|
+
it "should be able to handle NULL values when excluding multiple many_to_one associations" do
|
|
2831
|
+
@Album.exclude(:artist=>[@Artist.load(:id=>3), @Artist.new]).sql.should == 'SELECT * FROM albums WHERE ((albums.artist_id NOT IN (3)) OR (albums.artist_id IS NULL))'
|
|
2832
|
+
@Album.exclude(:artist=>[@Artist.new, @Artist.new]).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
2833
|
+
end
|
|
2834
|
+
|
|
2835
|
+
it "should be able to handle NULL values when excluding multiple one_to_many associations" do
|
|
2836
|
+
@Album.exclude(:tracks=>[@Track.load(:album_id=>3), @Track.new]).sql.should == 'SELECT * FROM albums WHERE ((albums.id NOT IN (3)) OR (albums.id IS NULL))'
|
|
2837
|
+
@Album.exclude(:tracks=>[@Track.new, @Track.new]).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
2838
|
+
end
|
|
2839
|
+
|
|
2840
|
+
it "should be able to handle NULL values when excluding multiple one_to_one associations" do
|
|
2841
|
+
@Album.exclude(:album_info=>[@AlbumInfo.load(:album_id=>3), @AlbumInfo.new]).sql.should == 'SELECT * FROM albums WHERE ((albums.id NOT IN (3)) OR (albums.id IS NULL))'
|
|
2842
|
+
@Album.exclude(:album_info=>[@AlbumInfo.new, @AlbumInfo.new]).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
2843
|
+
end
|
|
2844
|
+
|
|
2845
|
+
it "should be able to handle NULL values when excluding multiple many_to_many associations" do
|
|
2846
|
+
@Album.exclude(:tags=>[@Tag.load(:id=>3), @Tag.new]).sql.should == 'SELECT * FROM albums WHERE ((albums.id NOT IN (SELECT albums_tags.album_id FROM albums_tags WHERE ((albums_tags.tag_id IN (3)) AND (albums_tags.album_id IS NOT NULL)))) OR (albums.id IS NULL))'
|
|
2847
|
+
@Album.exclude(:tags=>[@Tag.new, @Tag.new]).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
2848
|
+
end
|
|
2849
|
+
|
|
2850
|
+
it "should be able to handle NULL values when excluding multiple many_to_one associations with composite keys" do
|
|
2851
|
+
@Album.exclude(:cartist=>[@Artist.load(:id1=>3, :id2=>4), @Artist.load(:id1=>3)]).sql.should == 'SELECT * FROM albums WHERE (((albums.artist_id1, albums.artist_id2) NOT IN ((3, 4))) OR (albums.artist_id1 IS NULL) OR (albums.artist_id2 IS NULL))'
|
|
2852
|
+
@Album.exclude(:cartist=>[@Artist.load(:id1=>3, :id2=>4), @Artist.new]).sql.should == 'SELECT * FROM albums WHERE (((albums.artist_id1, albums.artist_id2) NOT IN ((3, 4))) OR (albums.artist_id1 IS NULL) OR (albums.artist_id2 IS NULL))'
|
|
2853
|
+
end
|
|
2854
|
+
|
|
2855
|
+
it "should be able handle NULL values when excluding multiple one_to_many associations with composite keys" do
|
|
2856
|
+
@Album.exclude(:ctracks=>[@Track.load(:album_id1=>3, :album_id2=>4), @Track.load(:album_id1=>3)]).sql.should == 'SELECT * FROM albums WHERE (((albums.id1, albums.id2) NOT IN ((3, 4))) OR (albums.id1 IS NULL) OR (albums.id2 IS NULL))'
|
|
2857
|
+
@Album.exclude(:ctracks=>[@Track.load(:album_id1=>3, :album_id2=>4), @Track.new]).sql.should == 'SELECT * FROM albums WHERE (((albums.id1, albums.id2) NOT IN ((3, 4))) OR (albums.id1 IS NULL) OR (albums.id2 IS NULL))'
|
|
2858
|
+
end
|
|
2859
|
+
|
|
2860
|
+
it "should be able to handle NULL values when excluding multiple one_to_one associations with composite keys" do
|
|
2861
|
+
@Album.exclude(:calbum_info=>[@AlbumInfo.load(:album_id1=>3, :album_id2=>4), @AlbumInfo.load(:album_id1=>5)]).sql.should == 'SELECT * FROM albums WHERE (((albums.id1, albums.id2) NOT IN ((3, 4))) OR (albums.id1 IS NULL) OR (albums.id2 IS NULL))'
|
|
2862
|
+
@Album.exclude(:calbum_info=>[@AlbumInfo.load(:album_id1=>3, :album_id2=>4), @AlbumInfo.new]).sql.should == 'SELECT * FROM albums WHERE (((albums.id1, albums.id2) NOT IN ((3, 4))) OR (albums.id1 IS NULL) OR (albums.id2 IS NULL))'
|
|
2863
|
+
end
|
|
2864
|
+
|
|
2865
|
+
it "should be able to handle NULL values when excluding multiple many_to_many associations with composite keys" do
|
|
2866
|
+
@Album.exclude(:ctags=>[@Tag.load(:tid1=>3, :tid2=>4), @Tag.load(:tid1=>5)]).sql.should == 'SELECT * FROM albums WHERE (((albums.id1, albums.id2) NOT IN (SELECT albums_tags.album_id1, albums_tags.album_id2 FROM albums_tags WHERE (((albums_tags.tag_id1, albums_tags.tag_id2) IN ((3, 4))) AND (albums_tags.album_id1 IS NOT NULL) AND (albums_tags.album_id2 IS NOT NULL)))) OR (albums.id1 IS NULL) OR (albums.id2 IS NULL))'
|
|
2867
|
+
@Album.exclude(:ctags=>[@Tag.load(:tid1=>3, :tid2=>4), @Tag.new]).sql.should == 'SELECT * FROM albums WHERE (((albums.id1, albums.id2) NOT IN (SELECT albums_tags.album_id1, albums_tags.album_id2 FROM albums_tags WHERE (((albums_tags.tag_id1, albums_tags.tag_id2) IN ((3, 4))) AND (albums_tags.album_id1 IS NOT NULL) AND (albums_tags.album_id2 IS NOT NULL)))) OR (albums.id1 IS NULL) OR (albums.id2 IS NULL))'
|
|
2868
|
+
end
|
|
2869
|
+
|
|
2870
|
+
it "should be able to filter on many_to_one association datasets" do
|
|
2871
|
+
@Album.filter(:artist=>@Artist.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE (albums.artist_id IN (SELECT artists.id FROM artists WHERE ((x = 1) AND (artists.id IS NOT NULL))))'
|
|
2872
|
+
end
|
|
2873
|
+
|
|
2874
|
+
it "should be able to filter on one_to_many association datasets" do
|
|
2875
|
+
@Album.filter(:tracks=>@Track.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE (albums.id IN (SELECT tracks.album_id FROM tracks WHERE ((x = 1) AND (tracks.album_id IS NOT NULL))))'
|
|
2876
|
+
end
|
|
2877
|
+
|
|
2878
|
+
it "should be able to filter on one_to_one association datasets" do
|
|
2879
|
+
@Album.filter(:album_info=>@AlbumInfo.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE (albums.id IN (SELECT album_infos.album_id FROM album_infos WHERE ((x = 1) AND (album_infos.album_id IS NOT NULL))))'
|
|
2880
|
+
end
|
|
2881
|
+
|
|
2882
|
+
it "should be able to filter on many_to_many association datasets" do
|
|
2883
|
+
@Album.filter(:tags=>@Tag.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE (albums.id IN (SELECT albums_tags.album_id FROM albums_tags WHERE ((albums_tags.tag_id IN (SELECT tags.id FROM tags WHERE ((x = 1) AND (tags.id IS NOT NULL)))) AND (albums_tags.album_id IS NOT NULL))))'
|
|
2884
|
+
end
|
|
2885
|
+
|
|
2886
|
+
it "should be able to filter on many_to_one association datasets with composite keys" do
|
|
2887
|
+
@Album.filter(:cartist=>@Artist.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE ((albums.artist_id1, albums.artist_id2) IN (SELECT artists.id1, artists.id2 FROM artists WHERE ((x = 1) AND (artists.id1 IS NOT NULL) AND (artists.id2 IS NOT NULL))))'
|
|
2888
|
+
end
|
|
2889
|
+
|
|
2890
|
+
it "should be able to filter on one_to_many association datasets with composite keys" do
|
|
2891
|
+
@Album.filter(:ctracks=>@Track.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE ((albums.id1, albums.id2) IN (SELECT tracks.album_id1, tracks.album_id2 FROM tracks WHERE ((x = 1) AND (tracks.album_id1 IS NOT NULL) AND (tracks.album_id2 IS NOT NULL))))'
|
|
2892
|
+
end
|
|
2893
|
+
|
|
2894
|
+
it "should be able to filter on one_to_one association datasets with composite keys" do
|
|
2895
|
+
@Album.filter(:calbum_info=>@AlbumInfo.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE ((albums.id1, albums.id2) IN (SELECT album_infos.album_id1, album_infos.album_id2 FROM album_infos WHERE ((x = 1) AND (album_infos.album_id1 IS NOT NULL) AND (album_infos.album_id2 IS NOT NULL))))'
|
|
2896
|
+
end
|
|
2897
|
+
|
|
2898
|
+
it "should be able to filter on many_to_many association datasets with composite keys" do
|
|
2899
|
+
@Album.filter(:ctags=>@Tag.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE ((albums.id1, albums.id2) IN (SELECT albums_tags.album_id1, albums_tags.album_id2 FROM albums_tags WHERE (((albums_tags.tag_id1, albums_tags.tag_id2) IN (SELECT tags.tid1, tags.tid2 FROM tags WHERE ((x = 1) AND (tags.tid1 IS NOT NULL) AND (tags.tid2 IS NOT NULL)))) AND (albums_tags.album_id1 IS NOT NULL) AND (albums_tags.album_id2 IS NOT NULL))))'
|
|
2900
|
+
end
|
|
2901
|
+
|
|
2902
|
+
it "should be able to exclude on many_to_one association datasets" do
|
|
2903
|
+
@Album.exclude(:artist=>@Artist.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE ((albums.artist_id NOT IN (SELECT artists.id FROM artists WHERE ((x = 1) AND (artists.id IS NOT NULL)))) OR (albums.artist_id IS NULL))'
|
|
2904
|
+
end
|
|
2905
|
+
|
|
2906
|
+
it "should be able to exclude on one_to_many association datasets" do
|
|
2907
|
+
@Album.exclude(:tracks=>@Track.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE ((albums.id NOT IN (SELECT tracks.album_id FROM tracks WHERE ((x = 1) AND (tracks.album_id IS NOT NULL)))) OR (albums.id IS NULL))'
|
|
2908
|
+
end
|
|
2909
|
+
|
|
2910
|
+
it "should be able to exclude on one_to_one association datasets" do
|
|
2911
|
+
@Album.exclude(:album_info=>@AlbumInfo.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE ((albums.id NOT IN (SELECT album_infos.album_id FROM album_infos WHERE ((x = 1) AND (album_infos.album_id IS NOT NULL)))) OR (albums.id IS NULL))'
|
|
2912
|
+
end
|
|
2913
|
+
|
|
2914
|
+
it "should be able to exclude on many_to_many association datasets" do
|
|
2915
|
+
@Album.exclude(:tags=>@Tag.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE ((albums.id NOT IN (SELECT albums_tags.album_id FROM albums_tags WHERE ((albums_tags.tag_id IN (SELECT tags.id FROM tags WHERE ((x = 1) AND (tags.id IS NOT NULL)))) AND (albums_tags.album_id IS NOT NULL)))) OR (albums.id IS NULL))'
|
|
2916
|
+
end
|
|
2917
|
+
|
|
2918
|
+
it "should be able to exclude on many_to_one association datasets with composite keys" do
|
|
2919
|
+
@Album.exclude(:cartist=>@Artist.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE (((albums.artist_id1, albums.artist_id2) NOT IN (SELECT artists.id1, artists.id2 FROM artists WHERE ((x = 1) AND (artists.id1 IS NOT NULL) AND (artists.id2 IS NOT NULL)))) OR (albums.artist_id1 IS NULL) OR (albums.artist_id2 IS NULL))'
|
|
2920
|
+
end
|
|
2921
|
+
|
|
2922
|
+
it "should be able to exclude on one_to_many association datasets with composite keys" do
|
|
2923
|
+
@Album.exclude(:ctracks=>@Track.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE (((albums.id1, albums.id2) NOT IN (SELECT tracks.album_id1, tracks.album_id2 FROM tracks WHERE ((x = 1) AND (tracks.album_id1 IS NOT NULL) AND (tracks.album_id2 IS NOT NULL)))) OR (albums.id1 IS NULL) OR (albums.id2 IS NULL))'
|
|
2924
|
+
end
|
|
2925
|
+
|
|
2926
|
+
it "should be able to exclude on one_to_one association datasets with composite keys" do
|
|
2927
|
+
@Album.exclude(:calbum_info=>@AlbumInfo.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE (((albums.id1, albums.id2) NOT IN (SELECT album_infos.album_id1, album_infos.album_id2 FROM album_infos WHERE ((x = 1) AND (album_infos.album_id1 IS NOT NULL) AND (album_infos.album_id2 IS NOT NULL)))) OR (albums.id1 IS NULL) OR (albums.id2 IS NULL))'
|
|
2928
|
+
end
|
|
2929
|
+
|
|
2930
|
+
it "should be able to exclude on many_to_many association datasets with composite keys" do
|
|
2931
|
+
@Album.exclude(:ctags=>@Tag.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE (((albums.id1, albums.id2) NOT IN (SELECT albums_tags.album_id1, albums_tags.album_id2 FROM albums_tags WHERE (((albums_tags.tag_id1, albums_tags.tag_id2) IN (SELECT tags.tid1, tags.tid2 FROM tags WHERE ((x = 1) AND (tags.tid1 IS NOT NULL) AND (tags.tid2 IS NOT NULL)))) AND (albums_tags.album_id1 IS NOT NULL) AND (albums_tags.album_id2 IS NOT NULL)))) OR (albums.id1 IS NULL) OR (albums.id2 IS NULL))'
|
|
2932
|
+
end
|
|
2933
|
+
|
|
2934
|
+
it "should do a regular IN query if the dataset for a different model is used" do
|
|
2935
|
+
@Album.filter(:artist=>@Album.select(:x)).sql.should == 'SELECT * FROM albums WHERE (artist IN (SELECT x FROM albums))'
|
|
2936
|
+
end
|
|
2937
|
+
|
|
2938
|
+
it "should do a regular IN query if a non-model dataset is used" do
|
|
2939
|
+
@Album.filter(:artist=>@Album.db.from(:albums).select(:x)).sql.should == 'SELECT * FROM albums WHERE (artist IN (SELECT x FROM albums))'
|
|
2940
|
+
end
|
|
2941
|
+
end
|
|
2942
|
+
|
|
2943
|
+
describe "Sequel::Model Associations with clashing column names" do
|
|
2944
|
+
before do
|
|
2945
|
+
@db = Sequel.mock(:fetch=>{:id=>1, :object_id=>2})
|
|
2946
|
+
@Foo = Class.new(Sequel::Model(@db[:foos]))
|
|
2947
|
+
@Bar = Class.new(Sequel::Model(@db[:bars]))
|
|
2948
|
+
@Foo.columns :id, :object_id
|
|
2949
|
+
@Bar.columns :id, :object_id
|
|
2950
|
+
@Foo.def_column_alias(:obj_id, :object_id)
|
|
2951
|
+
@Bar.def_column_alias(:obj_id, :object_id)
|
|
2952
|
+
@Foo.one_to_many :bars, :primary_key=>:obj_id, :primary_key_column=>:object_id, :key=>:object_id, :key_method=>:obj_id, :class=>@Bar
|
|
2953
|
+
@Foo.one_to_one :bar, :primary_key=>:obj_id, :primary_key_column=>:object_id, :key=>:object_id, :key_method=>:obj_id, :class=>@Bar
|
|
2954
|
+
@Bar.many_to_one :foo, :key=>:obj_id, :key_column=>:object_id, :primary_key=>:object_id, :primary_key_method=>:obj_id, :class=>@Foo
|
|
2955
|
+
@Foo.many_to_many :mtmbars, :join_table=>:bars_foos, :left_primary_key=>:obj_id, :left_primary_key_column=>:object_id, :right_primary_key=>:object_id, :right_primary_key_method=>:obj_id, :left_key=>:foo_id, :right_key=>:object_id, :class=>@Bar
|
|
2956
|
+
@Bar.many_to_many :mtmfoos, :join_table=>:bars_foos, :left_primary_key=>:obj_id, :left_primary_key_column=>:object_id, :right_primary_key=>:object_id, :right_primary_key_method=>:obj_id, :left_key=>:object_id, :right_key=>:foo_id, :class=>@Foo
|
|
2957
|
+
@foo = @Foo.load(:id=>1, :object_id=>2)
|
|
2958
|
+
@bar = @Bar.load(:id=>1, :object_id=>2)
|
|
2959
|
+
@db.sqls
|
|
2960
|
+
end
|
|
2961
|
+
|
|
2962
|
+
it "should have working regular association methods" do
|
|
2963
|
+
@Bar.first.foo.should == @foo
|
|
2964
|
+
@db.sqls.should == ["SELECT * FROM bars LIMIT 1", "SELECT * FROM foos WHERE (foos.object_id = 2) LIMIT 1"]
|
|
2965
|
+
@Foo.first.bars.should == [@bar]
|
|
2966
|
+
@db.sqls.should == ["SELECT * FROM foos LIMIT 1", "SELECT * FROM bars WHERE (bars.object_id = 2)"]
|
|
2967
|
+
@Foo.first.bar.should == @bar
|
|
2968
|
+
@db.sqls.should == ["SELECT * FROM foos LIMIT 1", "SELECT * FROM bars WHERE (bars.object_id = 2) LIMIT 1"]
|
|
2969
|
+
@Foo.first.mtmbars.should == [@bar]
|
|
2970
|
+
@db.sqls.should == ["SELECT * FROM foos LIMIT 1", "SELECT bars.* FROM bars INNER JOIN bars_foos ON ((bars_foos.object_id = bars.object_id) AND (bars_foos.foo_id = 2))"]
|
|
2971
|
+
@Bar.first.mtmfoos.should == [@foo]
|
|
2972
|
+
@db.sqls.should == ["SELECT * FROM bars LIMIT 1", "SELECT foos.* FROM foos INNER JOIN bars_foos ON ((bars_foos.foo_id = foos.object_id) AND (bars_foos.object_id = 2))"]
|
|
2973
|
+
end
|
|
2974
|
+
|
|
2975
|
+
it "should have working eager loading methods" do
|
|
2976
|
+
@Bar.eager(:foo).all.map{|o| [o, o.foo]}.should == [[@bar, @foo]]
|
|
2977
|
+
@db.sqls.should == ["SELECT * FROM bars", "SELECT * FROM foos WHERE (foos.object_id IN (2))"]
|
|
2978
|
+
@Foo.eager(:bars).all.map{|o| [o, o.bars]}.should == [[@foo, [@bar]]]
|
|
2979
|
+
@db.sqls.should == ["SELECT * FROM foos", "SELECT * FROM bars WHERE (bars.object_id IN (2))"]
|
|
2980
|
+
@Foo.eager(:bar).all.map{|o| [o, o.bar]}.should == [[@foo, @bar]]
|
|
2981
|
+
@db.sqls.should == ["SELECT * FROM foos", "SELECT * FROM bars WHERE (bars.object_id IN (2))"]
|
|
2982
|
+
@db.fetch = [[{:id=>1, :object_id=>2}], [{:id=>1, :object_id=>2, :x_foreign_key_x=>2}]]
|
|
2983
|
+
@Foo.eager(:mtmbars).all.map{|o| [o, o.mtmbars]}.should == [[@foo, [@bar]]]
|
|
2984
|
+
@db.sqls.should == ["SELECT * FROM foos", "SELECT bars.*, bars_foos.foo_id AS x_foreign_key_x FROM bars INNER JOIN bars_foos ON ((bars_foos.object_id = bars.object_id) AND (bars_foos.foo_id IN (2)))"]
|
|
2985
|
+
@db.fetch = [[{:id=>1, :object_id=>2}], [{:id=>1, :object_id=>2, :x_foreign_key_x=>2}]]
|
|
2986
|
+
@Bar.eager(:mtmfoos).all.map{|o| [o, o.mtmfoos]}.should == [[@bar, [@foo]]]
|
|
2987
|
+
@db.sqls.should == ["SELECT * FROM bars", "SELECT foos.*, bars_foos.object_id AS x_foreign_key_x FROM foos INNER JOIN bars_foos ON ((bars_foos.foo_id = foos.object_id) AND (bars_foos.object_id IN (2)))"]
|
|
2988
|
+
end
|
|
2989
|
+
|
|
2990
|
+
it "should have working eager graphing methods" do
|
|
2991
|
+
@db.fetch = {:id=>1, :object_id=>2, :foo_id=>1, :foo_object_id=>2}
|
|
2992
|
+
@Bar.eager_graph(:foo).all.map{|o| [o, o.foo]}.should == [[@bar, @foo]]
|
|
2993
|
+
@db.sqls.should == ["SELECT bars.id, bars.object_id, foo.id AS foo_id, foo.object_id AS foo_object_id FROM bars LEFT OUTER JOIN foos AS foo ON (foo.object_id = bars.object_id)"]
|
|
2994
|
+
@db.fetch = {:id=>1, :object_id=>2, :bars_id=>1, :bars_object_id=>2}
|
|
2995
|
+
@Foo.eager_graph(:bars).all.map{|o| [o, o.bars]}.should == [[@foo, [@bar]]]
|
|
2996
|
+
@db.sqls.should == ["SELECT foos.id, foos.object_id, bars.id AS bars_id, bars.object_id AS bars_object_id FROM foos LEFT OUTER JOIN bars ON (bars.object_id = foos.object_id)"]
|
|
2997
|
+
@db.fetch = {:id=>1, :object_id=>2, :bar_id=>1, :bar_object_id=>2}
|
|
2998
|
+
@Foo.eager_graph(:bar).all.map{|o| [o, o.bar]}.should == [[@foo, @bar]]
|
|
2999
|
+
@db.sqls.should == ["SELECT foos.id, foos.object_id, bar.id AS bar_id, bar.object_id AS bar_object_id FROM foos LEFT OUTER JOIN bars AS bar ON (bar.object_id = foos.object_id)"]
|
|
3000
|
+
@db.fetch = {:id=>1, :object_id=>2, :mtmfoos_id=>1, :mtmfoos_object_id=>2}
|
|
3001
|
+
@Bar.eager_graph(:mtmfoos).all.map{|o| [o, o.mtmfoos]}.should == [[@bar, [@foo]]]
|
|
3002
|
+
@db.sqls.should == ["SELECT bars.id, bars.object_id, mtmfoos.id AS mtmfoos_id, mtmfoos.object_id AS mtmfoos_object_id FROM bars LEFT OUTER JOIN bars_foos ON (bars_foos.object_id = bars.object_id) LEFT OUTER JOIN foos AS mtmfoos ON (mtmfoos.object_id = bars_foos.foo_id)"]
|
|
3003
|
+
@db.fetch = {:id=>1, :object_id=>2, :mtmbars_id=>1, :mtmbars_object_id=>2}
|
|
3004
|
+
@Foo.eager_graph(:mtmbars).all.map{|o| [o, o.mtmbars]}.should == [[@foo, [@bar]]]
|
|
3005
|
+
@db.sqls.should == ["SELECT foos.id, foos.object_id, mtmbars.id AS mtmbars_id, mtmbars.object_id AS mtmbars_object_id FROM foos LEFT OUTER JOIN bars_foos ON (bars_foos.foo_id = foos.object_id) LEFT OUTER JOIN bars AS mtmbars ON (mtmbars.object_id = bars_foos.object_id)"]
|
|
3006
|
+
end
|
|
3007
|
+
|
|
3008
|
+
it "should have working filter by associations with model instances" do
|
|
3009
|
+
@Bar.first(:foo=>@foo).should == @bar
|
|
3010
|
+
@db.sqls.should == ["SELECT * FROM bars WHERE (bars.object_id = 2) LIMIT 1"]
|
|
3011
|
+
@Foo.first(:bars=>@bar).should == @foo
|
|
3012
|
+
@db.sqls.should == ["SELECT * FROM foos WHERE (foos.object_id = 2) LIMIT 1"]
|
|
3013
|
+
@Foo.first(:bar=>@bar).should == @foo
|
|
3014
|
+
@db.sqls.should == ["SELECT * FROM foos WHERE (foos.object_id = 2) LIMIT 1"]
|
|
3015
|
+
@Foo.first(:mtmbars=>@bar).should == @foo
|
|
3016
|
+
@db.sqls.should == ["SELECT * FROM foos WHERE (foos.object_id IN (SELECT bars_foos.foo_id FROM bars_foos WHERE ((bars_foos.object_id = 2) AND (bars_foos.foo_id IS NOT NULL)))) LIMIT 1"]
|
|
3017
|
+
@Bar.first(:mtmfoos=>@foo).should == @bar
|
|
3018
|
+
@db.sqls.should == ["SELECT * FROM bars WHERE (bars.object_id IN (SELECT bars_foos.object_id FROM bars_foos WHERE ((bars_foos.foo_id = 2) AND (bars_foos.object_id IS NOT NULL)))) LIMIT 1"]
|
|
3019
|
+
end
|
|
3020
|
+
|
|
3021
|
+
it "should have working modification methods" do
|
|
3022
|
+
b = @Bar.load(:id=>2, :object_id=>3)
|
|
3023
|
+
f = @Foo.load(:id=>2, :object_id=>3)
|
|
3024
|
+
@db.numrows = 1
|
|
3025
|
+
|
|
3026
|
+
@bar.foo = f
|
|
3027
|
+
@bar.obj_id.should == 3
|
|
3028
|
+
@foo.bar = @bar
|
|
3029
|
+
@bar.obj_id.should == 2
|
|
3030
|
+
|
|
3031
|
+
@foo.add_bar(b)
|
|
3032
|
+
@db.fetch = [[{:id=>1, :object_id=>2}, {:id=>2, :object_id=>2}], [{:id=>1, :object_id=>2}]]
|
|
3033
|
+
@foo.bars.should == [@bar, b]
|
|
3034
|
+
@foo.remove_bar(b)
|
|
3035
|
+
@foo.bars.should == [@bar]
|
|
3036
|
+
@foo.remove_all_bars
|
|
3037
|
+
@foo.bars.should == []
|
|
3038
|
+
|
|
3039
|
+
@db.fetch = [[{:id=>1, :object_id=>2}], [], [{:id=>2, :object_id=>2}]]
|
|
3040
|
+
@bar = @Bar.load(:id=>1, :object_id=>2)
|
|
3041
|
+
@foo.mtmbars.should == [@bar]
|
|
3042
|
+
@foo.remove_all_mtmbars
|
|
3043
|
+
@foo.mtmbars.should == []
|
|
3044
|
+
@foo.add_mtmbar(b)
|
|
3045
|
+
@foo.mtmbars.should == [b]
|
|
3046
|
+
@foo.remove_mtmbar(b)
|
|
3047
|
+
@foo.mtmbars.should == []
|
|
3048
|
+
|
|
3049
|
+
@db.fetch = [[{:id=>2, :object_id=>3}], [], [{:id=>2, :object_id=>3}]]
|
|
3050
|
+
@bar.add_mtmfoo(f)
|
|
3051
|
+
@bar.mtmfoos.should == [f]
|
|
3052
|
+
@bar.remove_all_mtmfoos
|
|
3053
|
+
@bar.mtmfoos.should == []
|
|
3054
|
+
@bar.add_mtmfoo(f)
|
|
3055
|
+
@bar.mtmfoos.should == [f]
|
|
3056
|
+
@bar.remove_mtmfoo(f)
|
|
3057
|
+
@bar.mtmfoos.should == []
|
|
3058
|
+
end
|
|
3059
|
+
end
|
|
3060
|
+
|
|
3061
|
+
describe "Sequel::Model Associations with non-column expression keys" do
|
|
3062
|
+
before do
|
|
3063
|
+
@db = Sequel.mock(:fetch=>{:id=>1, :object_ids=>[2]})
|
|
3064
|
+
@Foo = Class.new(Sequel::Model(@db[:foos]))
|
|
3065
|
+
@Bar = Class.new(Sequel::Model(@db[:bars]))
|
|
3066
|
+
@Foo.columns :id, :object_ids
|
|
3067
|
+
@Bar.columns :id, :object_ids
|
|
3068
|
+
m = Module.new{def obj_id; object_ids[0]; end}
|
|
3069
|
+
@Foo.include m
|
|
3070
|
+
@Bar.include m
|
|
3071
|
+
|
|
3072
|
+
@Foo.one_to_many :bars, :primary_key=>:obj_id, :primary_key_column=>Sequel.subscript(:object_ids, 0), :key=>Sequel.subscript(:object_ids, 0), :key_method=>:obj_id, :class=>@Bar
|
|
3073
|
+
@Foo.one_to_one :bar, :primary_key=>:obj_id, :primary_key_column=>Sequel.subscript(:object_ids, 0), :key=>Sequel.subscript(:object_ids, 0), :key_method=>:obj_id, :class=>@Bar
|
|
3074
|
+
@Bar.many_to_one :foo, :key=>:obj_id, :key_column=>Sequel.subscript(:object_ids, 0), :primary_key=>Sequel.subscript(:object_ids, 0), :primary_key_method=>:obj_id, :class=>@Foo
|
|
3075
|
+
@Foo.many_to_many :mtmbars, :join_table=>:bars_foos, :left_primary_key=>:obj_id, :left_primary_key_column=>Sequel.subscript(:object_ids, 0), :right_primary_key=>Sequel.subscript(:object_ids, 0), :right_primary_key_method=>:obj_id, :left_key=>Sequel.subscript(:foo_ids, 0), :right_key=>Sequel.subscript(:bar_ids, 0), :class=>@Bar
|
|
3076
|
+
@Bar.many_to_many :mtmfoos, :join_table=>:bars_foos, :left_primary_key=>:obj_id, :left_primary_key_column=>Sequel.subscript(:object_ids, 0), :right_primary_key=>Sequel.subscript(:object_ids, 0), :right_primary_key_method=>:obj_id, :left_key=>Sequel.subscript(:bar_ids, 0), :right_key=>Sequel.subscript(:foo_ids, 0), :class=>@Foo
|
|
3077
|
+
@foo = @Foo.load(:id=>1, :object_ids=>[2])
|
|
3078
|
+
@bar = @Bar.load(:id=>1, :object_ids=>[2])
|
|
3079
|
+
@db.sqls
|
|
3080
|
+
end
|
|
3081
|
+
|
|
3082
|
+
it "should have working regular association methods" do
|
|
3083
|
+
@Bar.first.foo.should == @foo
|
|
3084
|
+
@db.sqls.should == ["SELECT * FROM bars LIMIT 1", "SELECT * FROM foos WHERE (foos.object_ids[0] = 2) LIMIT 1"]
|
|
3085
|
+
@Foo.first.bars.should == [@bar]
|
|
3086
|
+
@db.sqls.should == ["SELECT * FROM foos LIMIT 1", "SELECT * FROM bars WHERE (bars.object_ids[0] = 2)"]
|
|
3087
|
+
@Foo.first.bar.should == @bar
|
|
3088
|
+
@db.sqls.should == ["SELECT * FROM foos LIMIT 1", "SELECT * FROM bars WHERE (bars.object_ids[0] = 2) LIMIT 1"]
|
|
3089
|
+
@Foo.first.mtmbars.should == [@bar]
|
|
3090
|
+
@db.sqls.should == ["SELECT * FROM foos LIMIT 1", "SELECT bars.* FROM bars INNER JOIN bars_foos ON ((bars_foos.bar_ids[0] = bars.object_ids[0]) AND (bars_foos.foo_ids[0] = 2))"]
|
|
3091
|
+
@Bar.first.mtmfoos.should == [@foo]
|
|
3092
|
+
@db.sqls.should == ["SELECT * FROM bars LIMIT 1", "SELECT foos.* FROM foos INNER JOIN bars_foos ON ((bars_foos.foo_ids[0] = foos.object_ids[0]) AND (bars_foos.bar_ids[0] = 2))"]
|
|
3093
|
+
end
|
|
3094
|
+
|
|
3095
|
+
it "should have working eager loading methods" do
|
|
3096
|
+
@Bar.eager(:foo).all.map{|o| [o, o.foo]}.should == [[@bar, @foo]]
|
|
3097
|
+
@db.sqls.should == ["SELECT * FROM bars", "SELECT * FROM foos WHERE (foos.object_ids[0] IN (2))"]
|
|
3098
|
+
@Foo.eager(:bars).all.map{|o| [o, o.bars]}.should == [[@foo, [@bar]]]
|
|
3099
|
+
@db.sqls.should == ["SELECT * FROM foos", "SELECT * FROM bars WHERE (bars.object_ids[0] IN (2))"]
|
|
3100
|
+
@Foo.eager(:bar).all.map{|o| [o, o.bar]}.should == [[@foo, @bar]]
|
|
3101
|
+
@db.sqls.should == ["SELECT * FROM foos", "SELECT * FROM bars WHERE (bars.object_ids[0] IN (2))"]
|
|
3102
|
+
@db.fetch = [[{:id=>1, :object_ids=>[2]}], [{:id=>1, :object_ids=>[2], :x_foreign_key_x=>2}]]
|
|
3103
|
+
@Foo.eager(:mtmbars).all.map{|o| [o, o.mtmbars]}.should == [[@foo, [@bar]]]
|
|
3104
|
+
@db.sqls.should == ["SELECT * FROM foos", "SELECT bars.*, bars_foos.foo_ids[0] AS x_foreign_key_x FROM bars INNER JOIN bars_foos ON ((bars_foos.bar_ids[0] = bars.object_ids[0]) AND (bars_foos.foo_ids[0] IN (2)))"]
|
|
3105
|
+
@db.fetch = [[{:id=>1, :object_ids=>[2]}], [{:id=>1, :object_ids=>[2], :x_foreign_key_x=>2}]]
|
|
3106
|
+
@Bar.eager(:mtmfoos).all.map{|o| [o, o.mtmfoos]}.should == [[@bar, [@foo]]]
|
|
3107
|
+
@db.sqls.should == ["SELECT * FROM bars", "SELECT foos.*, bars_foos.bar_ids[0] AS x_foreign_key_x FROM foos INNER JOIN bars_foos ON ((bars_foos.foo_ids[0] = foos.object_ids[0]) AND (bars_foos.bar_ids[0] IN (2)))"]
|
|
3108
|
+
end
|
|
3109
|
+
|
|
3110
|
+
it "should have working eager graphing methods" do
|
|
3111
|
+
@db.fetch = {:id=>1, :object_ids=>[2], :foo_id=>1, :foo_object_ids=>[2]}
|
|
3112
|
+
@Bar.eager_graph(:foo).all.map{|o| [o, o.foo]}.should == [[@bar, @foo]]
|
|
3113
|
+
@db.sqls.should == ["SELECT bars.id, bars.object_ids, foo.id AS foo_id, foo.object_ids AS foo_object_ids FROM bars LEFT OUTER JOIN foos AS foo ON (foo.object_ids[0] = bars.object_ids[0])"]
|
|
3114
|
+
@db.fetch = {:id=>1, :object_ids=>[2], :bars_id=>1, :bars_object_ids=>[2]}
|
|
3115
|
+
@Foo.eager_graph(:bars).all.map{|o| [o, o.bars]}.should == [[@foo, [@bar]]]
|
|
3116
|
+
@db.sqls.should == ["SELECT foos.id, foos.object_ids, bars.id AS bars_id, bars.object_ids AS bars_object_ids FROM foos LEFT OUTER JOIN bars ON (bars.object_ids[0] = foos.object_ids[0])"]
|
|
3117
|
+
@db.fetch = {:id=>1, :object_ids=>[2], :bar_id=>1, :bar_object_ids=>[2]}
|
|
3118
|
+
@Foo.eager_graph(:bar).all.map{|o| [o, o.bar]}.should == [[@foo, @bar]]
|
|
3119
|
+
@db.sqls.should == ["SELECT foos.id, foos.object_ids, bar.id AS bar_id, bar.object_ids AS bar_object_ids FROM foos LEFT OUTER JOIN bars AS bar ON (bar.object_ids[0] = foos.object_ids[0])"]
|
|
3120
|
+
@db.fetch = {:id=>1, :object_ids=>[2], :mtmfoos_id=>1, :mtmfoos_object_ids=>[2]}
|
|
3121
|
+
@Bar.eager_graph(:mtmfoos).all.map{|o| [o, o.mtmfoos]}.should == [[@bar, [@foo]]]
|
|
3122
|
+
@db.sqls.should == ["SELECT bars.id, bars.object_ids, mtmfoos.id AS mtmfoos_id, mtmfoos.object_ids AS mtmfoos_object_ids FROM bars LEFT OUTER JOIN bars_foos ON (bars_foos.bar_ids[0] = bars.object_ids[0]) LEFT OUTER JOIN foos AS mtmfoos ON (mtmfoos.object_ids[0] = bars_foos.foo_ids[0])"]
|
|
3123
|
+
@db.fetch = {:id=>1, :object_ids=>[2], :mtmbars_id=>1, :mtmbars_object_ids=>[2]}
|
|
3124
|
+
@Foo.eager_graph(:mtmbars).all.map{|o| [o, o.mtmbars]}.should == [[@foo, [@bar]]]
|
|
3125
|
+
@db.sqls.should == ["SELECT foos.id, foos.object_ids, mtmbars.id AS mtmbars_id, mtmbars.object_ids AS mtmbars_object_ids FROM foos LEFT OUTER JOIN bars_foos ON (bars_foos.foo_ids[0] = foos.object_ids[0]) LEFT OUTER JOIN bars AS mtmbars ON (mtmbars.object_ids[0] = bars_foos.bar_ids[0])"]
|
|
3126
|
+
end
|
|
3127
|
+
|
|
3128
|
+
it "should have working filter by associations with model instances" do
|
|
3129
|
+
@Bar.first(:foo=>@foo).should == @bar
|
|
3130
|
+
@db.sqls.should == ["SELECT * FROM bars WHERE (bars.object_ids[0] = 2) LIMIT 1"]
|
|
3131
|
+
@Foo.first(:bars=>@bar).should == @foo
|
|
3132
|
+
@db.sqls.should == ["SELECT * FROM foos WHERE (foos.object_ids[0] = 2) LIMIT 1"]
|
|
3133
|
+
@Foo.first(:bar=>@bar).should == @foo
|
|
3134
|
+
@db.sqls.should == ["SELECT * FROM foos WHERE (foos.object_ids[0] = 2) LIMIT 1"]
|
|
3135
|
+
@Foo.first(:mtmbars=>@bar).should == @foo
|
|
3136
|
+
@db.sqls.should == ["SELECT * FROM foos WHERE (foos.object_ids[0] IN (SELECT bars_foos.foo_ids[0] FROM bars_foos WHERE ((bars_foos.bar_ids[0] = 2) AND (bars_foos.foo_ids[0] IS NOT NULL)))) LIMIT 1"]
|
|
3137
|
+
@Bar.first(:mtmfoos=>@foo).should == @bar
|
|
3138
|
+
@db.sqls.should == ["SELECT * FROM bars WHERE (bars.object_ids[0] IN (SELECT bars_foos.bar_ids[0] FROM bars_foos WHERE ((bars_foos.foo_ids[0] = 2) AND (bars_foos.bar_ids[0] IS NOT NULL)))) LIMIT 1"]
|
|
3139
|
+
end
|
|
3140
|
+
|
|
3141
|
+
it "should have working filter by associations with model datasets" do
|
|
3142
|
+
@Bar.first(:foo=>@Foo.where(:id=>@foo.id)).should == @bar
|
|
3143
|
+
@db.sqls.should == ["SELECT * FROM bars WHERE (bars.object_ids[0] IN (SELECT foos.object_ids[0] FROM foos WHERE ((id = 1) AND (foos.object_ids[0] IS NOT NULL)))) LIMIT 1"]
|
|
3144
|
+
@Foo.first(:bars=>@Bar.where(:id=>@bar.id)).should == @foo
|
|
3145
|
+
@db.sqls.should == ["SELECT * FROM foos WHERE (foos.object_ids[0] IN (SELECT bars.object_ids[0] FROM bars WHERE ((id = 1) AND (bars.object_ids[0] IS NOT NULL)))) LIMIT 1"]
|
|
3146
|
+
@Foo.first(:bar=>@Bar.where(:id=>@bar.id)).should == @foo
|
|
3147
|
+
@db.sqls.should == ["SELECT * FROM foos WHERE (foos.object_ids[0] IN (SELECT bars.object_ids[0] FROM bars WHERE ((id = 1) AND (bars.object_ids[0] IS NOT NULL)))) LIMIT 1"]
|
|
3148
|
+
@Foo.first(:mtmbars=>@Bar.where(:id=>@bar.id)).should == @foo
|
|
3149
|
+
@db.sqls.should == ["SELECT * FROM foos WHERE (foos.object_ids[0] IN (SELECT bars_foos.foo_ids[0] FROM bars_foos WHERE ((bars_foos.bar_ids[0] IN (SELECT bars.object_ids[0] FROM bars WHERE ((id = 1) AND (bars.object_ids[0] IS NOT NULL)))) AND (bars_foos.foo_ids[0] IS NOT NULL)))) LIMIT 1"]
|
|
3150
|
+
@Bar.first(:mtmfoos=>@Foo.where(:id=>@foo.id)).should == @bar
|
|
3151
|
+
@db.sqls.should == ["SELECT * FROM bars WHERE (bars.object_ids[0] IN (SELECT bars_foos.bar_ids[0] FROM bars_foos WHERE ((bars_foos.foo_ids[0] IN (SELECT foos.object_ids[0] FROM foos WHERE ((id = 1) AND (foos.object_ids[0] IS NOT NULL)))) AND (bars_foos.bar_ids[0] IS NOT NULL)))) LIMIT 1"]
|
|
3152
|
+
end
|
|
3153
|
+
end
|
|
3154
|
+
|
|
3155
|
+
describe "Model#pk_or_nil" do
|
|
3156
|
+
before do
|
|
3157
|
+
@m = Class.new(Sequel::Model)
|
|
3158
|
+
@m.columns :id, :x, :y
|
|
3159
|
+
end
|
|
2674
3160
|
|
|
2675
|
-
it "
|
|
2676
|
-
@
|
|
3161
|
+
it "should be default return the value of the :id column" do
|
|
3162
|
+
m = @m.load(:id => 111, :x => 2, :y => 3)
|
|
3163
|
+
m.pk_or_nil.should == 111
|
|
3164
|
+
end
|
|
2677
3165
|
|
|
2678
|
-
|
|
2679
|
-
@
|
|
2680
|
-
@
|
|
2681
|
-
|
|
3166
|
+
it "should be return the primary key value for custom primary key" do
|
|
3167
|
+
@m.set_primary_key :x
|
|
3168
|
+
m = @m.load(:id => 111, :x => 2, :y => 3)
|
|
3169
|
+
m.pk_or_nil.should == 2
|
|
3170
|
+
end
|
|
2682
3171
|
|
|
2683
|
-
|
|
2684
|
-
@
|
|
2685
|
-
@
|
|
2686
|
-
|
|
2687
|
-
@c1.all_association_reflections.sort_by{|x|x[:name].to_s}.collect{|v| v[:class]}.should == [@c1, @c1]
|
|
3172
|
+
it "should be return the primary key value for composite primary key" do
|
|
3173
|
+
@m.set_primary_key [:y, :x]
|
|
3174
|
+
m = @m.load(:id => 111, :x => 2, :y => 3)
|
|
3175
|
+
m.pk_or_nil.should == [3, 2]
|
|
2688
3176
|
end
|
|
2689
3177
|
|
|
2690
|
-
it "
|
|
2691
|
-
@
|
|
3178
|
+
it "should raise if no primary key" do
|
|
3179
|
+
@m.set_primary_key nil
|
|
3180
|
+
m = @m.new(:id => 111, :x => 2, :y => 3)
|
|
3181
|
+
m.pk_or_nil.should be_nil
|
|
3182
|
+
|
|
3183
|
+
@m.no_primary_key
|
|
3184
|
+
m = @m.new(:id => 111, :x => 2, :y => 3)
|
|
3185
|
+
m.pk_or_nil.should be_nil
|
|
3186
|
+
end
|
|
3187
|
+
end
|
|
3188
|
+
|
|
3189
|
+
describe Sequel::Model, "#refresh" do
|
|
3190
|
+
before do
|
|
3191
|
+
@c = Class.new(Sequel::Model(:items)) do
|
|
3192
|
+
unrestrict_primary_key
|
|
3193
|
+
columns :id, :x
|
|
3194
|
+
end
|
|
3195
|
+
MODEL_DB.reset
|
|
2692
3196
|
end
|
|
2693
3197
|
|
|
2694
|
-
|
|
2695
|
-
@
|
|
2696
|
-
@
|
|
2697
|
-
@
|
|
2698
|
-
@
|
|
2699
|
-
@
|
|
3198
|
+
specify "should remove cached associations" do
|
|
3199
|
+
@c.many_to_one :node, :class=>@c
|
|
3200
|
+
@m = @c.new(:id => 555)
|
|
3201
|
+
@m.associations[:node] = 15
|
|
3202
|
+
@m.reload
|
|
3203
|
+
@m.associations.should == {}
|
|
3204
|
+
end
|
|
3205
|
+
end
|
|
3206
|
+
|
|
3207
|
+
describe "Model#freeze" do
|
|
3208
|
+
before do
|
|
3209
|
+
class ::Album < Sequel::Model
|
|
3210
|
+
columns :id
|
|
3211
|
+
class B < Sequel::Model
|
|
3212
|
+
columns :id, :album_id
|
|
3213
|
+
many_to_one :album, :class=>Album
|
|
3214
|
+
end
|
|
3215
|
+
one_to_one :b, :key=>:album_id, :class=>B
|
|
3216
|
+
end
|
|
3217
|
+
@o = Album.load(:id=>1).freeze
|
|
3218
|
+
MODEL_DB.sqls
|
|
3219
|
+
end
|
|
3220
|
+
after do
|
|
3221
|
+
Object.send(:remove_const, :Album)
|
|
3222
|
+
end
|
|
2700
3223
|
|
|
2701
|
-
|
|
2702
|
-
@
|
|
2703
|
-
@c1.association_reflection(:children)[:name].should == :children
|
|
2704
|
-
@c1.association_reflection(:children)[:type].should == :one_to_many
|
|
2705
|
-
@c1.association_reflection(:children)[:class].should == @c1
|
|
3224
|
+
it "should freeze the object's associations" do
|
|
3225
|
+
@o.associations.frozen?.should be_true
|
|
2706
3226
|
end
|
|
2707
3227
|
|
|
2708
|
-
it "
|
|
2709
|
-
|
|
2710
|
-
@
|
|
2711
|
-
@
|
|
2712
|
-
@c1.associate :one_to_many, :children, :class => @c1
|
|
2713
|
-
@c1.associations.sort_by{|x|x.to_s}.should == [:children, :parent]
|
|
3228
|
+
it "should not break associations getters" do
|
|
3229
|
+
Album::B.dataset._fetch = {:album_id=>1, :id=>2}
|
|
3230
|
+
@o.b.should == Album::B.load(:id=>2, :album_id=>1)
|
|
3231
|
+
@o.associations[:b].should be_nil
|
|
2714
3232
|
end
|
|
2715
3233
|
|
|
2716
|
-
it "
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
@
|
|
2720
|
-
c.associations.should == [:parent]
|
|
2721
|
-
c.associate :many_to_one, :parent2, :class => @c1
|
|
2722
|
-
@c1.associations.should == [:parent]
|
|
2723
|
-
c.associations.sort_by{|x| x.to_s}.should == [:parent, :parent2]
|
|
2724
|
-
c.instance_methods.map{|x| x.to_s}.should include('parent')
|
|
3234
|
+
it "should not break reciprocal associations" do
|
|
3235
|
+
b = Album::B.load(:id=>2, :album_id=>nil)
|
|
3236
|
+
b.album = @o
|
|
3237
|
+
@o.associations[:b].should be_nil
|
|
2725
3238
|
end
|
|
2726
3239
|
end
|