sequel 3.21.0 → 3.36.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 +855 -3
- data/MIT-LICENSE +1 -1
- data/README.rdoc +23 -7
- data/Rakefile +42 -24
- data/bin/sequel +26 -8
- data/doc/active_record.rdoc +1 -0
- data/doc/advanced_associations.rdoc +171 -11
- data/doc/association_basics.rdoc +293 -43
- data/doc/dataset_basics.rdoc +5 -5
- data/doc/dataset_filtering.rdoc +8 -0
- data/doc/mass_assignment.rdoc +56 -0
- data/doc/migration.rdoc +85 -552
- data/doc/model_hooks.rdoc +78 -27
- data/doc/object_model.rdoc +541 -0
- data/doc/opening_databases.rdoc +97 -50
- data/doc/prepared_statements.rdoc +40 -14
- data/doc/querying.rdoc +28 -4
- data/doc/reflection.rdoc +30 -4
- 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/schema_modification.rdoc +572 -0
- data/doc/sharding.rdoc +95 -3
- data/doc/testing.rdoc +129 -0
- data/doc/thread_safety.rdoc +17 -0
- data/doc/transactions.rdoc +137 -0
- data/doc/virtual_rows.rdoc +51 -2
- data/lib/sequel/adapters/ado/mssql.rb +18 -6
- data/lib/sequel/adapters/ado.rb +40 -18
- data/lib/sequel/adapters/amalgalite.rb +17 -9
- data/lib/sequel/adapters/db2.rb +175 -86
- data/lib/sequel/adapters/dbi.rb +15 -15
- data/lib/sequel/adapters/do/mysql.rb +17 -11
- data/lib/sequel/adapters/do/postgres.rb +1 -57
- data/lib/sequel/adapters/do/sqlite.rb +0 -10
- data/lib/sequel/adapters/do.rb +18 -36
- data/lib/sequel/adapters/firebird.rb +27 -208
- data/lib/sequel/adapters/ibmdb.rb +453 -0
- data/lib/sequel/adapters/informix.rb +6 -23
- data/lib/sequel/adapters/jdbc/as400.rb +16 -34
- data/lib/sequel/adapters/jdbc/db2.rb +47 -0
- data/lib/sequel/adapters/jdbc/derby.rb +287 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
- data/lib/sequel/adapters/jdbc/h2.rb +73 -31
- data/lib/sequel/adapters/jdbc/hsqldb.rb +184 -0
- data/lib/sequel/adapters/jdbc/informix.rb +21 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +29 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
- data/lib/sequel/adapters/jdbc/mysql.rb +7 -24
- data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
- data/lib/sequel/adapters/jdbc/postgresql.rb +58 -48
- 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 +66 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +265 -94
- data/lib/sequel/adapters/mock.rb +361 -0
- data/lib/sequel/adapters/mysql.rb +118 -222
- data/lib/sequel/adapters/mysql2.rb +58 -57
- data/lib/sequel/adapters/odbc/mssql.rb +15 -7
- data/lib/sequel/adapters/odbc.rb +28 -9
- data/lib/sequel/adapters/openbase.rb +3 -5
- data/lib/sequel/adapters/oracle.rb +349 -53
- data/lib/sequel/adapters/postgres.rb +356 -107
- data/lib/sequel/adapters/shared/access.rb +32 -9
- data/lib/sequel/adapters/shared/db2.rb +342 -0
- data/lib/sequel/adapters/shared/firebird.rb +221 -0
- data/lib/sequel/adapters/shared/informix.rb +53 -0
- data/lib/sequel/adapters/shared/mssql.rb +335 -118
- data/lib/sequel/adapters/shared/mysql.rb +340 -76
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +155 -0
- data/lib/sequel/adapters/shared/oracle.rb +243 -45
- data/lib/sequel/adapters/shared/postgres.rb +524 -279
- data/lib/sequel/adapters/shared/progress.rb +5 -8
- data/lib/sequel/adapters/shared/sqlite.rb +265 -89
- data/lib/sequel/adapters/sqlite.rb +101 -39
- data/lib/sequel/adapters/swift/mysql.rb +9 -12
- data/lib/sequel/adapters/swift/postgres.rb +9 -74
- data/lib/sequel/adapters/swift/sqlite.rb +8 -6
- data/lib/sequel/adapters/swift.rb +8 -7
- data/lib/sequel/adapters/tinytds.rb +161 -21
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +66 -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 +11 -1
- data/lib/sequel/connection_pool/sharded_threaded.rb +28 -2
- data/lib/sequel/connection_pool/single.rb +5 -0
- data/lib/sequel/connection_pool/threaded.rb +38 -14
- data/lib/sequel/connection_pool.rb +10 -2
- data/lib/sequel/core.rb +118 -11
- data/lib/sequel/database/connecting.rb +38 -28
- 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 +150 -46
- data/lib/sequel/database/query.rb +215 -65
- data/lib/sequel/database/schema_generator.rb +64 -20
- data/lib/sequel/database/schema_methods.rb +212 -54
- data/lib/sequel/dataset/actions.rb +322 -85
- data/lib/sequel/dataset/features.rb +96 -8
- data/lib/sequel/dataset/graph.rb +38 -11
- data/lib/sequel/dataset/misc.rb +50 -23
- data/lib/sequel/dataset/mutation.rb +12 -7
- data/lib/sequel/dataset/prepared_statements.rb +68 -30
- data/lib/sequel/dataset/query.rb +237 -44
- data/lib/sequel/dataset/sql.rb +698 -278
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/_pretty_table.rb +79 -0
- data/lib/sequel/extensions/arbitrary_servers.rb +108 -0
- data/lib/sequel/extensions/columns_introspection.rb +61 -0
- data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +16 -34
- data/lib/sequel/extensions/migration.rb +97 -11
- data/lib/sequel/extensions/named_timezones.rb +5 -0
- data/lib/sequel/extensions/null_dataset.rb +90 -0
- data/lib/sequel/extensions/pg_array.rb +460 -0
- data/lib/sequel/extensions/pg_array_ops.rb +220 -0
- data/lib/sequel/extensions/pg_auto_parameterize.rb +169 -0
- data/lib/sequel/extensions/pg_hstore.rb +296 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +259 -0
- data/lib/sequel/extensions/pg_inet.rb +89 -0
- data/lib/sequel/extensions/pg_json.rb +178 -0
- data/lib/sequel/extensions/pg_statement_cache.rb +316 -0
- data/lib/sequel/extensions/pretty_table.rb +5 -71
- data/lib/sequel/extensions/query.rb +1 -1
- 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 +251 -37
- data/lib/sequel/extensions/select_remove.rb +35 -0
- data/lib/sequel/extensions/server_block.rb +139 -0
- data/lib/sequel/extensions/sql_expr.rb +4 -110
- data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
- data/lib/sequel/extensions/to_dot.rb +95 -83
- data/lib/sequel/model/associations.rb +1187 -393
- data/lib/sequel/model/base.rb +578 -170
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +5 -1
- 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 +22 -4
- 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/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/defaults_setter.rb +58 -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 +123 -8
- 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 +58 -6
- data/lib/sequel/plugins/list.rb +12 -2
- data/lib/sequel/plugins/many_through_many.rb +79 -28
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
- data/lib/sequel/plugins/nested_attributes.rb +139 -63
- data/lib/sequel/plugins/optimistic_locking.rb +8 -0
- data/lib/sequel/plugins/prepared_statements.rb +167 -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 +29 -15
- data/lib/sequel/plugins/schema.rb +7 -2
- 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 +5 -3
- data/lib/sequel/plugins/static_cache.rb +99 -0
- data/lib/sequel/plugins/subclasses.rb +10 -2
- data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
- data/lib/sequel/plugins/timestamps.rb +1 -1
- 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 +1 -1
- data/lib/sequel/plugins/xml_serializer.rb +15 -4
- data/lib/sequel/sql.rb +526 -59
- data/lib/sequel/timezones.rb +57 -38
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/firebird_spec.rb +1 -1
- data/spec/adapters/mssql_spec.rb +142 -40
- data/spec/adapters/mysql_spec.rb +380 -234
- data/spec/adapters/oracle_spec.rb +67 -77
- data/spec/adapters/postgres_spec.rb +1050 -212
- data/spec/adapters/spec_helper.rb +8 -5
- data/spec/adapters/sqlite_spec.rb +139 -27
- data/spec/core/connection_pool_spec.rb +196 -93
- data/spec/core/database_spec.rb +879 -510
- data/spec/core/dataset_spec.rb +1415 -1086
- data/spec/core/expression_filters_spec.rb +554 -109
- data/spec/core/mock_adapter_spec.rb +449 -0
- data/spec/core/object_graph_spec.rb +86 -114
- data/spec/core/schema_generator_spec.rb +4 -4
- data/spec/core/schema_spec.rb +482 -38
- data/spec/core/spec_helper.rb +6 -48
- 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 +66 -32
- data/spec/extensions/association_proxies_spec.rb +4 -4
- 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/{core/core_sql_spec.rb → extensions/core_extensions_spec.rb} +119 -139
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +64 -0
- data/spec/extensions/dirty_spec.rb +155 -0
- data/spec/extensions/eager_each_spec.rb +34 -0
- data/spec/extensions/force_encoding_spec.rb +4 -2
- data/spec/extensions/hook_class_methods_spec.rb +69 -92
- data/spec/extensions/identity_map_spec.rb +131 -22
- 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 -6
- data/spec/extensions/lazy_attributes_spec.rb +16 -20
- data/spec/extensions/list_spec.rb +48 -39
- data/spec/extensions/many_through_many_spec.rb +283 -250
- 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 +251 -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 +105 -0
- data/spec/extensions/pg_array_spec.rb +196 -0
- data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
- data/spec/extensions/pg_hstore_ops_spec.rb +136 -0
- data/spec/extensions/pg_hstore_spec.rb +195 -0
- data/spec/extensions/pg_inet_spec.rb +44 -0
- data/spec/extensions/pg_json_spec.rb +101 -0
- data/spec/extensions/pg_statement_cache_spec.rb +209 -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 +168 -0
- data/spec/extensions/query_spec.rb +6 -0
- 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 +429 -22
- data/spec/extensions/schema_spec.rb +25 -21
- 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 +85 -43
- 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 +23 -29
- data/spec/extensions/skip_create_refresh_spec.rb +1 -1
- data/spec/extensions/spec_helper.rb +22 -61
- data/spec/extensions/sql_expr_spec.rb +29 -60
- data/spec/extensions/static_cache_spec.rb +145 -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 +4 -7
- data/spec/extensions/touch_spec.rb +13 -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 +30 -51
- data/spec/extensions/validation_helpers_spec.rb +16 -35
- 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 +9 -3
- data/spec/integration/dataset_test.rb +605 -91
- data/spec/integration/eager_loader_test.rb +19 -21
- data/spec/integration/migrator_test.rb +2 -3
- data/spec/integration/model_test.rb +81 -2
- data/spec/integration/plugin_test.rb +454 -143
- data/spec/integration/prepared_statement_test.rb +263 -128
- data/spec/integration/schema_test.rb +309 -43
- data/spec/integration/spec_helper.rb +40 -30
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +183 -8
- data/spec/integration/type_test.rb +18 -4
- data/spec/model/association_reflection_spec.rb +201 -7
- data/spec/model/associations_spec.rb +1067 -661
- data/spec/model/base_spec.rb +329 -95
- data/spec/model/dataset_methods_spec.rb +7 -27
- data/spec/model/eager_loading_spec.rb +677 -676
- data/spec/model/hooks_spec.rb +349 -67
- data/spec/model/model_spec.rb +240 -168
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +490 -232
- data/spec/model/spec_helper.rb +14 -71
- data/spec/model/validations_spec.rb +11 -0
- data/spec/rcov.opts +2 -0
- metadata +178 -80
|
@@ -1,85 +1,84 @@
|
|
|
1
1
|
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
2
2
|
|
|
3
3
|
describe "NestedAttributes plugin" do
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
ds_mod = Module.new do
|
|
10
|
-
def empty?; false; end
|
|
11
|
-
define_method(:insert) do |h|
|
|
12
|
-
x = ii.call
|
|
13
|
-
mods << [:i, first_source, h, x]
|
|
14
|
-
x
|
|
15
|
-
end
|
|
16
|
-
define_method(:insert_select) do |h|
|
|
17
|
-
x = ii.call
|
|
18
|
-
mods << [:is, first_source, h, x]
|
|
19
|
-
h.merge(:id=>x)
|
|
20
|
-
end
|
|
21
|
-
define_method(:update) do |h|
|
|
22
|
-
mods << [:u, first_source, h, literal(opts[:where])]
|
|
23
|
-
1
|
|
24
|
-
end
|
|
25
|
-
define_method(:delete) do
|
|
26
|
-
mods << [:d, first_source, literal(opts[:where])]
|
|
27
|
-
1
|
|
28
|
-
end
|
|
4
|
+
def check_sqls(should, is)
|
|
5
|
+
if should.is_a?(Array)
|
|
6
|
+
should.should include(is)
|
|
7
|
+
else
|
|
8
|
+
should.should == is
|
|
29
9
|
end
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def check_sql_array(*shoulds)
|
|
13
|
+
sqls = @db.sqls
|
|
14
|
+
shoulds.length.should == sqls.length
|
|
15
|
+
shoulds.zip(sqls){|s, i| check_sqls(s, i)}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
before do
|
|
19
|
+
@db = Sequel.mock(:autoid=>1, :numrows=>1)
|
|
20
|
+
@c = Class.new(Sequel::Model(@db))
|
|
37
21
|
@c.plugin :nested_attributes
|
|
38
22
|
@Artist = Class.new(@c).set_dataset(:artists)
|
|
39
23
|
@Album = Class.new(@c).set_dataset(:albums)
|
|
40
24
|
@Tag = Class.new(@c).set_dataset(:tags)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
25
|
+
@Concert = Class.new(@c).set_dataset(:concerts)
|
|
26
|
+
@Artist.plugin :skip_create_refresh
|
|
27
|
+
@Album.plugin :skip_create_refresh
|
|
28
|
+
@Tag.plugin :skip_create_refresh
|
|
29
|
+
@Concert.plugin :skip_create_refresh
|
|
44
30
|
@Artist.columns :id, :name
|
|
45
31
|
@Album.columns :id, :name, :artist_id
|
|
46
32
|
@Tag.columns :id, :name
|
|
33
|
+
@Concert.columns :tour, :date, :artist_id, :playlist
|
|
34
|
+
@Concert.set_primary_key([:tour, :date])
|
|
35
|
+
@Concert.unrestrict_primary_key
|
|
47
36
|
@Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id
|
|
37
|
+
@Artist.one_to_many :concerts, :class=>@Concert, :key=>:artist_id
|
|
48
38
|
@Artist.one_to_one :first_album, :class=>@Album, :key=>:artist_id
|
|
49
39
|
@Album.many_to_one :artist, :class=>@Artist
|
|
50
40
|
@Album.many_to_many :tags, :class=>@Tag, :left_key=>:album_id, :right_key=>:tag_id, :join_table=>:at
|
|
51
41
|
@Artist.nested_attributes :albums, :first_album, :destroy=>true, :remove=>true
|
|
42
|
+
@Artist.nested_attributes :concerts, :destroy=>true, :remove=>true
|
|
52
43
|
@Album.nested_attributes :artist, :tags, :destroy=>true, :remove=>true
|
|
44
|
+
@db.sqls
|
|
53
45
|
end
|
|
54
46
|
|
|
55
47
|
it "should support creating new many_to_one objects" do
|
|
56
48
|
a = @Album.new({:name=>'Al', :artist_attributes=>{:name=>'Ar'}})
|
|
57
|
-
@
|
|
49
|
+
@db.sqls.should == []
|
|
58
50
|
a.save
|
|
59
|
-
|
|
51
|
+
check_sql_array("INSERT INTO artists (name) VALUES ('Ar')",
|
|
52
|
+
["INSERT INTO albums (name, artist_id) VALUES ('Al', 1)", "INSERT INTO albums (artist_id, name) VALUES (1, 'Al')"])
|
|
60
53
|
end
|
|
61
54
|
|
|
62
55
|
it "should support creating new one_to_one objects" do
|
|
63
56
|
a = @Artist.new(:name=>'Ar')
|
|
64
57
|
a.id = 1
|
|
65
58
|
a.first_album_attributes = {:name=>'Al'}
|
|
66
|
-
@
|
|
59
|
+
@db.sqls.should == []
|
|
67
60
|
a.save
|
|
68
|
-
|
|
61
|
+
check_sql_array(["INSERT INTO artists (name, id) VALUES ('Ar', 1)", "INSERT INTO artists (id, name) VALUES (1, 'Ar')"],
|
|
62
|
+
"INSERT INTO albums (name) VALUES ('Al')",
|
|
63
|
+
"UPDATE albums SET artist_id = NULL WHERE ((artist_id = 1) AND (id != 2))",
|
|
64
|
+
["UPDATE albums SET artist_id = 1, name = 'Al' WHERE (id = 2)", "UPDATE albums SET name = 'Al', artist_id = 1 WHERE (id = 2)"])
|
|
69
65
|
end
|
|
70
66
|
|
|
71
67
|
it "should support creating new one_to_many objects" do
|
|
72
68
|
a = @Artist.new({:name=>'Ar', :albums_attributes=>[{:name=>'Al'}]})
|
|
73
|
-
@
|
|
69
|
+
@db.sqls.should == []
|
|
74
70
|
a.save
|
|
75
|
-
|
|
71
|
+
check_sql_array("INSERT INTO artists (name) VALUES ('Ar')",
|
|
72
|
+
["INSERT INTO albums (artist_id, name) VALUES (1, 'Al')", "INSERT INTO albums (name, artist_id) VALUES ('Al', 1)"])
|
|
76
73
|
end
|
|
77
74
|
|
|
78
75
|
it "should support creating new many_to_many objects" do
|
|
79
76
|
a = @Album.new({:name=>'Al', :tags_attributes=>[{:name=>'T'}]})
|
|
80
|
-
@
|
|
77
|
+
@db.sqls.should == []
|
|
81
78
|
a.save
|
|
82
|
-
|
|
79
|
+
check_sql_array("INSERT INTO albums (name) VALUES ('Al')",
|
|
80
|
+
"INSERT INTO tags (name) VALUES ('T')",
|
|
81
|
+
["INSERT INTO at (album_id, tag_id) VALUES (1, 2)", "INSERT INTO at (tag_id, album_id) VALUES (2, 1)"])
|
|
83
82
|
end
|
|
84
83
|
|
|
85
84
|
it "should add new objects to the cached association array as soon as the *_attributes= method is called" do
|
|
@@ -88,14 +87,64 @@ describe "NestedAttributes plugin" do
|
|
|
88
87
|
a.albums.first.tags.should == [@Tag.new(:name=>'T')]
|
|
89
88
|
end
|
|
90
89
|
|
|
90
|
+
it "should support creating new objects with composite primary keys" do
|
|
91
|
+
insert = nil
|
|
92
|
+
@Concert.class_eval do
|
|
93
|
+
define_method :_insert do
|
|
94
|
+
insert = values
|
|
95
|
+
end
|
|
96
|
+
def before_create # Have to define the CPK somehow.
|
|
97
|
+
self.tour = 'To'
|
|
98
|
+
self.date = '2004-04-05'
|
|
99
|
+
super
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
a = @Artist.new({:name=>'Ar', :concerts_attributes=>[{:playlist=>'Pl'}]})
|
|
103
|
+
@db.sqls.should == []
|
|
104
|
+
a.save
|
|
105
|
+
@db.sqls.should == ["INSERT INTO artists (name) VALUES ('Ar')"]
|
|
106
|
+
insert.should == {:tour=>'To', :date=>'2004-04-05', :artist_id=>1, :playlist=>'Pl'}
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it "should support creating new objects with specific primary keys if :unmatched_pk => :create is set" do
|
|
110
|
+
@Artist.nested_attributes :albums, :unmatched_pk=>:create
|
|
111
|
+
insert = nil
|
|
112
|
+
@Album.class_eval do
|
|
113
|
+
unrestrict_primary_key
|
|
114
|
+
define_method :_insert do
|
|
115
|
+
insert = values
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
a = @Artist.new({:name=>'Ar', :albums_attributes=>[{:id=>7, :name=>'Al'}]})
|
|
119
|
+
@db.sqls.should == []
|
|
120
|
+
a.save
|
|
121
|
+
@db.sqls.should == ["INSERT INTO artists (name) VALUES ('Ar')"]
|
|
122
|
+
insert.should == {:artist_id=>1, :name=>'Al', :id=>7}
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it "should support creating new objects with specific composite primary keys if :unmatched_pk => :create is set" do
|
|
126
|
+
insert = nil
|
|
127
|
+
@Artist.nested_attributes :concerts, :unmatched_pk=>:create
|
|
128
|
+
@Concert.class_eval do
|
|
129
|
+
define_method :_insert do
|
|
130
|
+
insert = values
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
a = @Artist.new({:name=>'Ar', :concerts_attributes=>[{:tour=>'To', :date=>'2004-04-05', :playlist=>'Pl'}]})
|
|
134
|
+
@db.sqls.should == []
|
|
135
|
+
a.save
|
|
136
|
+
@db.sqls.should == ["INSERT INTO artists (name) VALUES ('Ar')"]
|
|
137
|
+
insert.should == {:tour=>'To', :date=>'2004-04-05', :artist_id=>1, :playlist=>'Pl'}
|
|
138
|
+
end
|
|
139
|
+
|
|
91
140
|
it "should support updating many_to_one objects" do
|
|
92
141
|
al = @Album.load(:id=>10, :name=>'Al')
|
|
93
142
|
ar = @Artist.load(:id=>20, :name=>'Ar')
|
|
94
143
|
al.associations[:artist] = ar
|
|
95
144
|
al.set(:artist_attributes=>{:id=>'20', :name=>'Ar2'})
|
|
96
|
-
@
|
|
145
|
+
@db.sqls.should == []
|
|
97
146
|
al.save
|
|
98
|
-
@
|
|
147
|
+
@db.sqls.should == ["UPDATE albums SET name = 'Al' WHERE (id = 10)", "UPDATE artists SET name = 'Ar2' WHERE (id = 20)"]
|
|
99
148
|
end
|
|
100
149
|
|
|
101
150
|
it "should support updating one_to_one objects" do
|
|
@@ -103,9 +152,9 @@ describe "NestedAttributes plugin" do
|
|
|
103
152
|
ar = @Artist.load(:id=>20, :name=>'Ar')
|
|
104
153
|
ar.associations[:first_album] = al
|
|
105
154
|
ar.set(:first_album_attributes=>{:id=>10, :name=>'Al2'})
|
|
106
|
-
@
|
|
155
|
+
@db.sqls.should == []
|
|
107
156
|
ar.save
|
|
108
|
-
@
|
|
157
|
+
@db.sqls.should == ["UPDATE artists SET name = 'Ar' WHERE (id = 20)", "UPDATE albums SET name = 'Al2' WHERE (id = 10)"]
|
|
109
158
|
end
|
|
110
159
|
|
|
111
160
|
it "should support updating one_to_many objects" do
|
|
@@ -113,9 +162,19 @@ describe "NestedAttributes plugin" do
|
|
|
113
162
|
ar = @Artist.load(:id=>20, :name=>'Ar')
|
|
114
163
|
ar.associations[:albums] = [al]
|
|
115
164
|
ar.set(:albums_attributes=>[{:id=>10, :name=>'Al2'}])
|
|
116
|
-
@
|
|
165
|
+
@db.sqls.should == []
|
|
166
|
+
ar.save
|
|
167
|
+
@db.sqls.should == ["UPDATE artists SET name = 'Ar' WHERE (id = 20)", "UPDATE albums SET name = 'Al2' WHERE (id = 10)"]
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
it "should support updating one_to_many objects with _delete/_remove flags set to false" do
|
|
171
|
+
al = @Album.load(:id=>10, :name=>'Al')
|
|
172
|
+
ar = @Artist.load(:id=>20, :name=>'Ar')
|
|
173
|
+
ar.associations[:albums] = [al]
|
|
174
|
+
ar.set(:albums_attributes=>[{:id=>10, :name=>'Al2', :_delete => 'f', :_remove => '0'}])
|
|
175
|
+
@db.sqls.should == []
|
|
117
176
|
ar.save
|
|
118
|
-
@
|
|
177
|
+
@db.sqls.should == ["UPDATE artists SET name = 'Ar' WHERE (id = 20)", "UPDATE albums SET name = 'Al2' WHERE (id = 10)"]
|
|
119
178
|
end
|
|
120
179
|
|
|
121
180
|
it "should support updating many_to_many objects" do
|
|
@@ -123,19 +182,39 @@ describe "NestedAttributes plugin" do
|
|
|
123
182
|
t = @Tag.load(:id=>20, :name=>'T')
|
|
124
183
|
a.associations[:tags] = [t]
|
|
125
184
|
a.set(:tags_attributes=>[{:id=>20, :name=>'T2'}])
|
|
126
|
-
@
|
|
185
|
+
@db.sqls.should == []
|
|
186
|
+
a.save
|
|
187
|
+
@db.sqls.should == ["UPDATE albums SET name = 'Al' WHERE (id = 10)", "UPDATE tags SET name = 'T2' WHERE (id = 20)"]
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
it "should support updating many_to_many objects with _delete/_remove flags set to false" do
|
|
191
|
+
a = @Album.load(:id=>10, :name=>'Al')
|
|
192
|
+
t = @Tag.load(:id=>20, :name=>'T')
|
|
193
|
+
a.associations[:tags] = [t]
|
|
194
|
+
a.set(:tags_attributes=>[{:id=>20, :name=>'T2', '_delete' => false, '_remove' => 'F'}])
|
|
195
|
+
@db.sqls.should == []
|
|
127
196
|
a.save
|
|
128
|
-
@
|
|
197
|
+
@db.sqls.should == ["UPDATE albums SET name = 'Al' WHERE (id = 10)", "UPDATE tags SET name = 'T2' WHERE (id = 20)"]
|
|
129
198
|
end
|
|
130
199
|
|
|
200
|
+
it "should support updating objects with composite primary keys" do
|
|
201
|
+
ar = @Artist.load(:id=>10, :name=>'Ar')
|
|
202
|
+
co = @Concert.load(:tour=>'To', :date=>'2004-04-05', :playlist=>'Pl')
|
|
203
|
+
ar.associations[:concerts] = [co]
|
|
204
|
+
ar.set(:concerts_attributes=>[{:tour=>'To', :date=>'2004-04-05', :playlist=>'Pl2'}])
|
|
205
|
+
@db.sqls.should == []
|
|
206
|
+
ar.save
|
|
207
|
+
check_sql_array("UPDATE artists SET name = 'Ar' WHERE (id = 10)", ["UPDATE concerts SET playlist = 'Pl2' WHERE ((tour = 'To') AND (date = '2004-04-05'))", "UPDATE concerts SET playlist = 'Pl2' WHERE ((date = '2004-04-05') AND (tour = 'To'))"])
|
|
208
|
+
end
|
|
209
|
+
|
|
131
210
|
it "should support removing many_to_one objects" do
|
|
132
211
|
al = @Album.load(:id=>10, :name=>'Al')
|
|
133
212
|
ar = @Artist.load(:id=>20, :name=>'Ar')
|
|
134
213
|
al.associations[:artist] = ar
|
|
135
214
|
al.set(:artist_attributes=>{:id=>'20', :_remove=>'1'})
|
|
136
|
-
@
|
|
215
|
+
@db.sqls.should == []
|
|
137
216
|
al.save
|
|
138
|
-
|
|
217
|
+
check_sql_array(["UPDATE albums SET artist_id = NULL, name = 'Al' WHERE (id = 10)", "UPDATE albums SET name = 'Al', artist_id = NULL WHERE (id = 10)"])
|
|
139
218
|
end
|
|
140
219
|
|
|
141
220
|
it "should support removing one_to_one objects" do
|
|
@@ -143,10 +222,9 @@ describe "NestedAttributes plugin" do
|
|
|
143
222
|
ar = @Artist.load(:id=>20, :name=>'Ar')
|
|
144
223
|
ar.associations[:first_album] = al
|
|
145
224
|
ar.set(:first_album_attributes=>{:id=>10, :_remove=>'t'})
|
|
146
|
-
@
|
|
225
|
+
@db.sqls.should == []
|
|
147
226
|
ar.save
|
|
148
|
-
@
|
|
149
|
-
|
|
227
|
+
@db.sqls.should == ["UPDATE albums SET artist_id = NULL WHERE (artist_id = 20)", "UPDATE artists SET name = 'Ar' WHERE (id = 20)"]
|
|
150
228
|
end
|
|
151
229
|
|
|
152
230
|
it "should support removing one_to_many objects" do
|
|
@@ -154,9 +232,12 @@ describe "NestedAttributes plugin" do
|
|
|
154
232
|
ar = @Artist.load(:id=>20, :name=>'Ar')
|
|
155
233
|
ar.associations[:albums] = [al]
|
|
156
234
|
ar.set(:albums_attributes=>[{:id=>10, :_remove=>'t'}])
|
|
157
|
-
@
|
|
235
|
+
@db.sqls.should == []
|
|
236
|
+
@Album.dataset._fetch = {:id=>1}
|
|
158
237
|
ar.save
|
|
159
|
-
|
|
238
|
+
check_sql_array("SELECT 1 AS one FROM albums WHERE ((albums.artist_id = 20) AND (id = 10)) LIMIT 1",
|
|
239
|
+
["UPDATE albums SET artist_id = NULL, name = 'Al' WHERE (id = 10)", "UPDATE albums SET name = 'Al', artist_id = NULL WHERE (id = 10)"],
|
|
240
|
+
"UPDATE artists SET name = 'Ar' WHERE (id = 20)")
|
|
160
241
|
end
|
|
161
242
|
|
|
162
243
|
it "should support removing many_to_many objects" do
|
|
@@ -164,19 +245,33 @@ describe "NestedAttributes plugin" do
|
|
|
164
245
|
t = @Tag.load(:id=>20, :name=>'T')
|
|
165
246
|
a.associations[:tags] = [t]
|
|
166
247
|
a.set(:tags_attributes=>[{:id=>20, :_remove=>true}])
|
|
167
|
-
@
|
|
248
|
+
@db.sqls.should == []
|
|
168
249
|
a.save
|
|
169
|
-
@
|
|
250
|
+
@db.sqls.should == ["DELETE FROM at WHERE ((album_id = 10) AND (tag_id = 20))", "UPDATE albums SET name = 'Al' WHERE (id = 10)"]
|
|
170
251
|
end
|
|
171
252
|
|
|
253
|
+
it "should support removing objects with composite primary keys" do
|
|
254
|
+
ar = @Artist.load(:id=>10, :name=>'Ar')
|
|
255
|
+
co = @Concert.load(:tour=>'To', :date=>'2004-04-05', :playlist=>'Pl')
|
|
256
|
+
ar.associations[:concerts] = [co]
|
|
257
|
+
ar.set(:concerts_attributes=>[{:tour=>'To', :date=>'2004-04-05', :_remove=>'t'}])
|
|
258
|
+
@db.sqls.should == []
|
|
259
|
+
@Concert.dataset._fetch = {:id=>1}
|
|
260
|
+
ar.save
|
|
261
|
+
check_sql_array(["SELECT 1 AS one FROM concerts WHERE ((concerts.artist_id = 10) AND (tour = 'To') AND (date = '2004-04-05')) LIMIT 1", "SELECT 1 AS one FROM concerts WHERE ((concerts.artist_id = 10) AND (date = '2004-04-05') AND (tour = 'To')) LIMIT 1"],
|
|
262
|
+
["UPDATE concerts SET artist_id = NULL, playlist = 'Pl' WHERE ((tour = 'To') AND (date = '2004-04-05'))", "UPDATE concerts SET playlist = 'Pl', artist_id = NULL WHERE ((tour = 'To') AND (date = '2004-04-05'))", "UPDATE concerts SET artist_id = NULL, playlist = 'Pl' WHERE ((date = '2004-04-05') AND (tour = 'To'))", "UPDATE concerts SET playlist = 'Pl', artist_id = NULL WHERE ((date = '2004-04-05') AND (tour = 'To'))"],
|
|
263
|
+
"UPDATE artists SET name = 'Ar' WHERE (id = 10)")
|
|
264
|
+
end
|
|
265
|
+
|
|
172
266
|
it "should support destroying many_to_one objects" do
|
|
173
267
|
al = @Album.load(:id=>10, :name=>'Al')
|
|
174
268
|
ar = @Artist.load(:id=>20, :name=>'Ar')
|
|
175
269
|
al.associations[:artist] = ar
|
|
176
270
|
al.set(:artist_attributes=>{:id=>'20', :_delete=>'1'})
|
|
177
|
-
@
|
|
271
|
+
@db.sqls.should == []
|
|
178
272
|
al.save
|
|
179
|
-
|
|
273
|
+
check_sql_array(["UPDATE albums SET artist_id = NULL, name = 'Al' WHERE (id = 10)", "UPDATE albums SET name = 'Al', artist_id = NULL WHERE (id = 10)"],
|
|
274
|
+
"DELETE FROM artists WHERE (id = 20)")
|
|
180
275
|
end
|
|
181
276
|
|
|
182
277
|
it "should support destroying one_to_one objects" do
|
|
@@ -184,9 +279,9 @@ describe "NestedAttributes plugin" do
|
|
|
184
279
|
ar = @Artist.load(:id=>20, :name=>'Ar')
|
|
185
280
|
ar.associations[:first_album] = al
|
|
186
281
|
ar.set(:first_album_attributes=>{:id=>10, :_delete=>'t'})
|
|
187
|
-
@
|
|
282
|
+
@db.sqls.should == []
|
|
188
283
|
ar.save
|
|
189
|
-
@
|
|
284
|
+
@db.sqls.should == ["UPDATE artists SET name = 'Ar' WHERE (id = 20)", "DELETE FROM albums WHERE (id = 10)"]
|
|
190
285
|
end
|
|
191
286
|
|
|
192
287
|
it "should support destroying one_to_many objects" do
|
|
@@ -194,9 +289,9 @@ describe "NestedAttributes plugin" do
|
|
|
194
289
|
ar = @Artist.load(:id=>20, :name=>'Ar')
|
|
195
290
|
ar.associations[:albums] = [al]
|
|
196
291
|
ar.set(:albums_attributes=>[{:id=>10, :_delete=>'t'}])
|
|
197
|
-
@
|
|
292
|
+
@db.sqls.should == []
|
|
198
293
|
ar.save
|
|
199
|
-
@
|
|
294
|
+
@db.sqls.should == ["UPDATE artists SET name = 'Ar' WHERE (id = 20)", "DELETE FROM albums WHERE (id = 10)"]
|
|
200
295
|
end
|
|
201
296
|
|
|
202
297
|
it "should support destroying many_to_many objects" do
|
|
@@ -204,19 +299,29 @@ describe "NestedAttributes plugin" do
|
|
|
204
299
|
t = @Tag.load(:id=>20, :name=>'T')
|
|
205
300
|
a.associations[:tags] = [t]
|
|
206
301
|
a.set(:tags_attributes=>[{:id=>20, :_delete=>true}])
|
|
207
|
-
@
|
|
302
|
+
@db.sqls.should == []
|
|
208
303
|
a.save
|
|
209
|
-
@
|
|
304
|
+
@db.sqls.should == ["DELETE FROM at WHERE ((album_id = 10) AND (tag_id = 20))", "UPDATE albums SET name = 'Al' WHERE (id = 10)", "DELETE FROM tags WHERE (id = 20)"]
|
|
210
305
|
end
|
|
211
306
|
|
|
307
|
+
it "should support destroying objects with composite primary keys" do
|
|
308
|
+
ar = @Artist.load(:id=>10, :name=>'Ar')
|
|
309
|
+
co = @Concert.load(:tour=>'To', :date=>'2004-04-05', :playlist=>'Pl')
|
|
310
|
+
ar.associations[:concerts] = [co]
|
|
311
|
+
ar.set(:concerts_attributes=>[{:tour=>'To', :date=>'2004-04-05', :_delete=>'t'}])
|
|
312
|
+
@db.sqls.should == []
|
|
313
|
+
ar.save
|
|
314
|
+
check_sql_array("UPDATE artists SET name = 'Ar' WHERE (id = 10)", ["DELETE FROM concerts WHERE ((tour = 'To') AND (date = '2004-04-05'))", "DELETE FROM concerts WHERE ((date = '2004-04-05') AND (tour = 'To'))"])
|
|
315
|
+
end
|
|
316
|
+
|
|
212
317
|
it "should support both string and symbol keys in nested attribute hashes" do
|
|
213
318
|
a = @Album.load(:id=>10, :name=>'Al')
|
|
214
319
|
t = @Tag.load(:id=>20, :name=>'T')
|
|
215
320
|
a.associations[:tags] = [t]
|
|
216
321
|
a.set('tags_attributes'=>[{'id'=>20, '_delete'=>true}])
|
|
217
|
-
@
|
|
322
|
+
@db.sqls.should == []
|
|
218
323
|
a.save
|
|
219
|
-
@
|
|
324
|
+
@db.sqls.should == ["DELETE FROM at WHERE ((album_id = 10) AND (tag_id = 20))", "UPDATE albums SET name = 'Al' WHERE (id = 10)", "DELETE FROM tags WHERE (id = 20)"]
|
|
220
325
|
end
|
|
221
326
|
|
|
222
327
|
it "should support using a hash instead of an array for to_many nested attributes" do
|
|
@@ -224,9 +329,9 @@ describe "NestedAttributes plugin" do
|
|
|
224
329
|
t = @Tag.load(:id=>20, :name=>'T')
|
|
225
330
|
a.associations[:tags] = [t]
|
|
226
331
|
a.set('tags_attributes'=>{'1'=>{'id'=>20, '_delete'=>true}})
|
|
227
|
-
@
|
|
332
|
+
@db.sqls.should == []
|
|
228
333
|
a.save
|
|
229
|
-
@
|
|
334
|
+
@db.sqls.should == ["DELETE FROM at WHERE ((album_id = 10) AND (tag_id = 20))", "UPDATE albums SET name = 'Al' WHERE (id = 10)", "DELETE FROM tags WHERE (id = 20)"]
|
|
230
335
|
end
|
|
231
336
|
|
|
232
337
|
it "should only allow destroying associated objects if :destroy option is used in the nested_attributes call" do
|
|
@@ -263,11 +368,41 @@ describe "NestedAttributes plugin" do
|
|
|
263
368
|
ar = @Artist.load(:id=>20, :name=>'Ar')
|
|
264
369
|
ar.associations[:albums] = [al]
|
|
265
370
|
ar.set(:albums_attributes=>[{:id=>30, :_delete=>'t'}])
|
|
266
|
-
@
|
|
371
|
+
@db.sqls.should == []
|
|
267
372
|
ar.save
|
|
268
|
-
@
|
|
373
|
+
@db.sqls.should == ["UPDATE artists SET name = 'Ar' WHERE (id = 20)"]
|
|
269
374
|
end
|
|
270
375
|
|
|
376
|
+
it "should not raise an Error if an unmatched primary key is given, if the :unmatched_pk=>:ignore option is used" do
|
|
377
|
+
@Artist.nested_attributes :albums, :unmatched_pk=>:ignore
|
|
378
|
+
al = @Album.load(:id=>10, :name=>'Al')
|
|
379
|
+
ar = @Artist.load(:id=>20, :name=>'Ar')
|
|
380
|
+
ar.associations[:albums] = [al]
|
|
381
|
+
ar.set(:albums_attributes=>[{:id=>30, :_delete=>'t'}])
|
|
382
|
+
@db.sqls.should == []
|
|
383
|
+
ar.save
|
|
384
|
+
@db.sqls.should == ["UPDATE artists SET name = 'Ar' WHERE (id = 20)"]
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
it "should raise an Error if a composite primary key is given in a nested attribute hash, but no matching associated object exists" do
|
|
388
|
+
ar = @Artist.load(:id=>10, :name=>'Ar')
|
|
389
|
+
co = @Concert.load(:tour=>'To', :date=>'2004-04-05', :playlist=>'Pl')
|
|
390
|
+
ar.associations[:concerts] = [co]
|
|
391
|
+
proc{ar.set(:concerts_attributes=>[{:tour=>'To', :date=>'2004-04-04', :_delete=>'t'}])}.should raise_error(Sequel::Error)
|
|
392
|
+
proc{ar.set(:concerts_attributes=>[{:tour=>'To', :date=>'2004-04-05', :_delete=>'t'}])}.should_not raise_error(Sequel::Error)
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
it "should not raise an Error if an unmatched composite primary key is given, if the :strict=>false option is used" do
|
|
396
|
+
@Artist.nested_attributes :concerts, :strict=>false
|
|
397
|
+
ar = @Artist.load(:id=>10, :name=>'Ar')
|
|
398
|
+
co = @Concert.load(:tour=>'To', :date=>'2004-04-05', :playlist=>'Pl')
|
|
399
|
+
ar.associations[:concerts] = [co]
|
|
400
|
+
ar.set(:concerts_attributes=>[{:tour=>'To', :date=>'2004-04-06', :_delete=>'t'}])
|
|
401
|
+
@db.sqls.should == []
|
|
402
|
+
ar.save
|
|
403
|
+
@db.sqls.should == ["UPDATE artists SET name = 'Ar' WHERE (id = 10)"]
|
|
404
|
+
end
|
|
405
|
+
|
|
271
406
|
it "should not save if nested attribute is not valid and should include nested attribute validation errors in the main object's validation errors" do
|
|
272
407
|
@Artist.class_eval do
|
|
273
408
|
def validate
|
|
@@ -276,10 +411,10 @@ describe "NestedAttributes plugin" do
|
|
|
276
411
|
end
|
|
277
412
|
end
|
|
278
413
|
a = @Album.new(:name=>'Al', :artist_attributes=>{:name=>'Ar'})
|
|
279
|
-
@
|
|
414
|
+
@db.sqls.should == []
|
|
280
415
|
proc{a.save}.should raise_error(Sequel::ValidationFailed)
|
|
281
416
|
a.errors.full_messages.should == ['artist name cannot be Ar']
|
|
282
|
-
@
|
|
417
|
+
@db.sqls.should == []
|
|
283
418
|
# Should preserve attributes
|
|
284
419
|
a.artist.name.should == 'Ar'
|
|
285
420
|
end
|
|
@@ -294,9 +429,10 @@ describe "NestedAttributes plugin" do
|
|
|
294
429
|
end
|
|
295
430
|
end
|
|
296
431
|
a = @Album.new(:name=>'Al', :artist_attributes=>{:name=>'Ar'})
|
|
297
|
-
@
|
|
432
|
+
@db.sqls.should == []
|
|
298
433
|
a.save
|
|
299
|
-
|
|
434
|
+
check_sql_array("INSERT INTO artists (name) VALUES ('Ar')",
|
|
435
|
+
["INSERT INTO albums (artist_id, name) VALUES (1, 'Al')", "INSERT INTO albums (name, artist_id) VALUES ('Al', 1)"])
|
|
300
436
|
end
|
|
301
437
|
|
|
302
438
|
it "should not attempt to validate nested attributes if the :validate=>false option is passed to save" do
|
|
@@ -307,23 +443,25 @@ describe "NestedAttributes plugin" do
|
|
|
307
443
|
end
|
|
308
444
|
end
|
|
309
445
|
a = @Album.new(:name=>'Al', :artist_attributes=>{:name=>'Ar'})
|
|
310
|
-
@
|
|
446
|
+
@db.sqls.should == []
|
|
311
447
|
a.save(:validate=>false)
|
|
312
|
-
|
|
448
|
+
check_sql_array("INSERT INTO artists (name) VALUES ('Ar')",
|
|
449
|
+
["INSERT INTO albums (artist_id, name) VALUES (1, 'Al')", "INSERT INTO albums (name, artist_id) VALUES ('Al', 1)"])
|
|
313
450
|
end
|
|
314
451
|
|
|
315
452
|
it "should not accept nested attributes unless explicitly specified" do
|
|
316
453
|
@Artist.many_to_many :tags, :class=>@Tag, :left_key=>:album_id, :right_key=>:tag_id, :join_table=>:at
|
|
317
454
|
proc{@Artist.create({:name=>'Ar', :tags_attributes=>[{:name=>'T'}]})}.should raise_error(Sequel::Error)
|
|
318
|
-
@
|
|
455
|
+
@db.sqls.should == []
|
|
319
456
|
end
|
|
320
457
|
|
|
321
458
|
it "should save when save_changes or update is called if nested attribute associated objects changed but there are no changes to the main object" do
|
|
322
459
|
al = @Album.load(:id=>10, :name=>'Al')
|
|
323
460
|
ar = @Artist.load(:id=>20, :name=>'Ar')
|
|
324
461
|
al.associations[:artist] = ar
|
|
462
|
+
@db.sqls.should == []
|
|
325
463
|
al.update(:artist_attributes=>{:id=>'20', :name=>'Ar2'})
|
|
326
|
-
@
|
|
464
|
+
@db.sqls.should == ["UPDATE artists SET name = 'Ar2' WHERE (id = 20)"]
|
|
327
465
|
end
|
|
328
466
|
|
|
329
467
|
it "should have a :limit option limiting the amount of entries" do
|
|
@@ -331,19 +469,40 @@ describe "NestedAttributes plugin" do
|
|
|
331
469
|
arr = [{:name=>'T'}]
|
|
332
470
|
proc{@Album.new({:name=>'Al', :tags_attributes=>arr*3})}.should raise_error(Sequel::Error)
|
|
333
471
|
a = @Album.new({:name=>'Al', :tags_attributes=>arr*2})
|
|
334
|
-
@
|
|
472
|
+
@db.sqls.should == []
|
|
335
473
|
a.save
|
|
336
|
-
|
|
474
|
+
check_sql_array("INSERT INTO albums (name) VALUES ('Al')",
|
|
475
|
+
"INSERT INTO tags (name) VALUES ('T')",
|
|
476
|
+
["INSERT INTO at (album_id, tag_id) VALUES (1, 2)", "INSERT INTO at (tag_id, album_id) VALUES (2, 1)"],
|
|
477
|
+
"INSERT INTO tags (name) VALUES ('T')",
|
|
478
|
+
["INSERT INTO at (album_id, tag_id) VALUES (1, 4)", "INSERT INTO at (tag_id, album_id) VALUES (4, 1)"])
|
|
337
479
|
end
|
|
338
480
|
|
|
339
481
|
it "should accept a block that each hash gets passed to determine if it should be processed" do
|
|
340
482
|
@Album.nested_attributes(:tags){|h| h[:name].empty?}
|
|
341
483
|
a = @Album.new({:name=>'Al', :tags_attributes=>[{:name=>'T'}, {:name=>''}, {:name=>'T2'}]})
|
|
342
|
-
@
|
|
484
|
+
@db.sqls.should == []
|
|
343
485
|
a.save
|
|
344
|
-
|
|
486
|
+
check_sql_array("INSERT INTO albums (name) VALUES ('Al')",
|
|
487
|
+
"INSERT INTO tags (name) VALUES ('T')",
|
|
488
|
+
["INSERT INTO at (album_id, tag_id) VALUES (1, 2)", "INSERT INTO at (tag_id, album_id) VALUES (2, 1)"],
|
|
489
|
+
"INSERT INTO tags (name) VALUES ('T2')",
|
|
490
|
+
["INSERT INTO at (album_id, tag_id) VALUES (1, 4)", "INSERT INTO at (tag_id, album_id) VALUES (4, 1)"])
|
|
345
491
|
end
|
|
346
492
|
|
|
493
|
+
it "should accept a :transform block that returns a changed attributes hash" do
|
|
494
|
+
@Album.nested_attributes :tags, :transform=>proc{|parent, hash| hash[:name] << parent.name; hash }
|
|
495
|
+
a = @Album.new(:name => 'Al')
|
|
496
|
+
a.set(:tags_attributes=>[{:name=>'T'}, {:name=>'T2'}])
|
|
497
|
+
@db.sqls.should == []
|
|
498
|
+
a.save
|
|
499
|
+
check_sql_array("INSERT INTO albums (name) VALUES ('Al')",
|
|
500
|
+
"INSERT INTO tags (name) VALUES ('TAl')",
|
|
501
|
+
["INSERT INTO at (album_id, tag_id) VALUES (1, 2)", "INSERT INTO at (tag_id, album_id) VALUES (2, 1)"],
|
|
502
|
+
"INSERT INTO tags (name) VALUES ('T2Al')",
|
|
503
|
+
["INSERT INTO at (album_id, tag_id) VALUES (1, 4)", "INSERT INTO at (tag_id, album_id) VALUES (4, 1)"])
|
|
504
|
+
end
|
|
505
|
+
|
|
347
506
|
it "should return objects created/modified in the internal methods" do
|
|
348
507
|
@Album.nested_attributes :tags, :remove=>true, :strict=>false
|
|
349
508
|
objs = []
|
|
@@ -355,7 +514,7 @@ describe "NestedAttributes plugin" do
|
|
|
355
514
|
a = @Album.new(:name=>'Al')
|
|
356
515
|
a.associations[:tags] = [@Tag.load(:id=>6, :name=>'A'), @Tag.load(:id=>7, :name=>'A2')]
|
|
357
516
|
a.tags_attributes = [{:id=>6, :name=>'T'}, {:id=>7, :name=>'T2', :_remove=>true}, {:name=>'T3'}, {:id=>8, :name=>'T4'}, {:id=>9, :name=>'T5', :_remove=>true}]
|
|
358
|
-
objs.should == [[@Tag.load(:id=>6, :name=>'T'), :update], [@Tag.load(:id=>7, :name=>'A2'), :remove], [@Tag.new(:name=>'T3'), :create]
|
|
517
|
+
objs.should == [[@Tag.load(:id=>6, :name=>'T'), :update], [@Tag.load(:id=>7, :name=>'A2'), :remove], [@Tag.new(:name=>'T3'), :create]]
|
|
359
518
|
end
|
|
360
519
|
|
|
361
520
|
it "should raise an error if updating modifies the associated objects keys" do
|
|
@@ -387,9 +546,12 @@ describe "NestedAttributes plugin" do
|
|
|
387
546
|
t = @Tag.load(:id=>30, :name=>'T', :number=>10)
|
|
388
547
|
al.associations[:tags] = [t]
|
|
389
548
|
al.set(:tags_attributes=>[{:id=>30, :name=>'T2'}, {:name=>'T3'}])
|
|
390
|
-
@
|
|
549
|
+
@db.sqls.should == []
|
|
391
550
|
al.save
|
|
392
|
-
|
|
551
|
+
check_sql_array("UPDATE albums SET name = 'Al' WHERE (id = 10)",
|
|
552
|
+
"UPDATE tags SET name = 'T2' WHERE (id = 30)",
|
|
553
|
+
"INSERT INTO tags (name) VALUES ('T3')",
|
|
554
|
+
["INSERT INTO at (album_id, tag_id) VALUES (10, 1)", "INSERT INTO at (tag_id, album_id) VALUES (1, 10)"])
|
|
393
555
|
proc{al.set(:tags_attributes=>[{:id=>30, :name=>'T2', :number=>3}])}.should raise_error(Sequel::Error)
|
|
394
556
|
proc{al.set(:tags_attributes=>[{:name=>'T2', :number=>3}])}.should raise_error(Sequel::Error)
|
|
395
557
|
end
|