activerecord 2.0.5 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (289) hide show
  1. data/CHANGELOG +168 -6
  2. data/README +27 -22
  3. data/RUNNING_UNIT_TESTS +7 -4
  4. data/Rakefile +22 -25
  5. data/lib/active_record.rb +8 -2
  6. data/lib/active_record/aggregations.rb +21 -12
  7. data/lib/active_record/association_preload.rb +277 -0
  8. data/lib/active_record/associations.rb +481 -295
  9. data/lib/active_record/associations/association_collection.rb +162 -37
  10. data/lib/active_record/associations/association_proxy.rb +71 -7
  11. data/lib/active_record/associations/belongs_to_association.rb +5 -3
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +5 -6
  13. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +12 -64
  14. data/lib/active_record/associations/has_many_association.rb +8 -73
  15. data/lib/active_record/associations/has_many_through_association.rb +68 -117
  16. data/lib/active_record/associations/has_one_association.rb +7 -5
  17. data/lib/active_record/associations/has_one_through_association.rb +28 -0
  18. data/lib/active_record/attribute_methods.rb +69 -19
  19. data/lib/active_record/base.rb +496 -275
  20. data/lib/active_record/calculations.rb +28 -21
  21. data/lib/active_record/callbacks.rb +9 -38
  22. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +3 -2
  23. data/lib/active_record/connection_adapters/abstract/database_statements.rb +2 -2
  24. data/lib/active_record/connection_adapters/abstract/query_cache.rb +6 -0
  25. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +232 -45
  26. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +141 -27
  27. data/lib/active_record/connection_adapters/abstract_adapter.rb +9 -13
  28. data/lib/active_record/connection_adapters/mysql_adapter.rb +57 -24
  29. data/lib/active_record/connection_adapters/postgresql_adapter.rb +143 -42
  30. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -1
  31. data/lib/active_record/connection_adapters/sqlite_adapter.rb +18 -10
  32. data/lib/active_record/dirty.rb +158 -0
  33. data/lib/active_record/fixtures.rb +121 -156
  34. data/lib/active_record/locking/optimistic.rb +14 -11
  35. data/lib/active_record/locking/pessimistic.rb +2 -2
  36. data/lib/active_record/migration.rb +157 -77
  37. data/lib/active_record/named_scope.rb +163 -0
  38. data/lib/active_record/observer.rb +19 -5
  39. data/lib/active_record/reflection.rb +34 -14
  40. data/lib/active_record/schema.rb +7 -14
  41. data/lib/active_record/schema_dumper.rb +4 -4
  42. data/lib/active_record/serialization.rb +5 -5
  43. data/lib/active_record/serializers/json_serializer.rb +37 -28
  44. data/lib/active_record/serializers/xml_serializer.rb +52 -29
  45. data/lib/active_record/test_case.rb +36 -0
  46. data/lib/active_record/timestamp.rb +4 -4
  47. data/lib/active_record/transactions.rb +3 -3
  48. data/lib/active_record/validations.rb +182 -248
  49. data/lib/active_record/version.rb +2 -2
  50. data/test/{fixtures → assets}/example.log +0 -0
  51. data/test/{fixtures → assets}/flowers.jpg +0 -0
  52. data/test/cases/aaa_create_tables_test.rb +24 -0
  53. data/test/cases/active_schema_test_mysql.rb +95 -0
  54. data/test/cases/active_schema_test_postgresql.rb +24 -0
  55. data/test/{adapter_test.rb → cases/adapter_test.rb} +15 -14
  56. data/test/{adapter_test_sqlserver.rb → cases/adapter_test_sqlserver.rb} +95 -95
  57. data/test/{aggregations_test.rb → cases/aggregations_test.rb} +20 -20
  58. data/test/{ar_schema_test.rb → cases/ar_schema_test.rb} +6 -6
  59. data/test/cases/associations/belongs_to_associations_test.rb +412 -0
  60. data/test/{associations → cases/associations}/callbacks_test.rb +24 -10
  61. data/test/{associations → cases/associations}/cascaded_eager_loading_test.rb +18 -17
  62. data/test/cases/associations/eager_load_nested_include_test.rb +83 -0
  63. data/test/{associations → cases/associations}/eager_singularization_test.rb +5 -5
  64. data/test/{associations → cases/associations}/eager_test.rb +216 -51
  65. data/test/{associations → cases/associations}/extension_test.rb +8 -8
  66. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +684 -0
  67. data/test/cases/associations/has_many_associations_test.rb +932 -0
  68. data/test/cases/associations/has_many_through_associations_test.rb +190 -0
  69. data/test/cases/associations/has_one_associations_test.rb +323 -0
  70. data/test/cases/associations/has_one_through_associations_test.rb +74 -0
  71. data/test/{associations → cases/associations}/inner_join_association_test.rb +20 -20
  72. data/test/{associations → cases/associations}/join_model_test.rb +175 -35
  73. data/test/cases/associations_test.rb +262 -0
  74. data/test/{attribute_methods_test.rb → cases/attribute_methods_test.rb} +103 -11
  75. data/test/{base_test.rb → cases/base_test.rb} +338 -191
  76. data/test/{binary_test.rb → cases/binary_test.rb} +6 -4
  77. data/test/{calculations_test.rb → cases/calculations_test.rb} +35 -23
  78. data/test/{callbacks_test.rb → cases/callbacks_test.rb} +7 -7
  79. data/test/{class_inheritable_attributes_test.rb → cases/class_inheritable_attributes_test.rb} +3 -3
  80. data/test/{column_alias_test.rb → cases/column_alias_test.rb} +3 -3
  81. data/test/{connection_test_firebird.rb → cases/connection_test_firebird.rb} +2 -2
  82. data/test/{connection_test_mysql.rb → cases/connection_test_mysql.rb} +2 -2
  83. data/test/{copy_table_test_sqlite.rb → cases/copy_table_test_sqlite.rb} +13 -13
  84. data/test/{datatype_test_postgresql.rb → cases/datatype_test_postgresql.rb} +8 -8
  85. data/test/{date_time_test.rb → cases/date_time_test.rb} +5 -5
  86. data/test/{default_test_firebird.rb → cases/default_test_firebird.rb} +3 -3
  87. data/test/{defaults_test.rb → cases/defaults_test.rb} +8 -6
  88. data/test/{deprecated_finder_test.rb → cases/deprecated_finder_test.rb} +3 -3
  89. data/test/cases/dirty_test.rb +163 -0
  90. data/test/cases/finder_respond_to_test.rb +76 -0
  91. data/test/{finder_test.rb → cases/finder_test.rb} +266 -33
  92. data/test/{fixtures_test.rb → cases/fixtures_test.rb} +88 -72
  93. data/test/cases/helper.rb +47 -0
  94. data/test/{inheritance_test.rb → cases/inheritance_test.rb} +61 -17
  95. data/test/cases/invalid_date_test.rb +24 -0
  96. data/test/{json_serialization_test.rb → cases/json_serialization_test.rb} +36 -11
  97. data/test/{lifecycle_test.rb → cases/lifecycle_test.rb} +16 -13
  98. data/test/{locking_test.rb → cases/locking_test.rb} +17 -10
  99. data/test/{method_scoping_test.rb → cases/method_scoping_test.rb} +75 -39
  100. data/test/{migration_test.rb → cases/migration_test.rb} +420 -80
  101. data/test/{migration_test_firebird.rb → cases/migration_test_firebird.rb} +3 -3
  102. data/test/{mixin_test.rb → cases/mixin_test.rb} +7 -6
  103. data/test/{modules_test.rb → cases/modules_test.rb} +11 -6
  104. data/test/{multiple_db_test.rb → cases/multiple_db_test.rb} +5 -5
  105. data/test/cases/named_scope_test.rb +157 -0
  106. data/test/{pk_test.rb → cases/pk_test.rb} +10 -10
  107. data/test/{query_cache_test.rb → cases/query_cache_test.rb} +12 -10
  108. data/test/{readonly_test.rb → cases/readonly_test.rb} +11 -11
  109. data/test/{reflection_test.rb → cases/reflection_test.rb} +15 -14
  110. data/test/{reserved_word_test_mysql.rb → cases/reserved_word_test_mysql.rb} +4 -5
  111. data/test/{schema_authorization_test_postgresql.rb → cases/schema_authorization_test_postgresql.rb} +5 -5
  112. data/test/cases/schema_dumper_test.rb +138 -0
  113. data/test/cases/schema_test_postgresql.rb +102 -0
  114. data/test/{serialization_test.rb → cases/serialization_test.rb} +7 -7
  115. data/test/{synonym_test_oracle.rb → cases/synonym_test_oracle.rb} +5 -5
  116. data/test/{table_name_test_sqlserver.rb → cases/table_name_test_sqlserver.rb} +3 -3
  117. data/test/{threaded_connections_test.rb → cases/threaded_connections_test.rb} +7 -7
  118. data/test/{transactions_test.rb → cases/transactions_test.rb} +31 -5
  119. data/test/{unconnected_test.rb → cases/unconnected_test.rb} +2 -2
  120. data/test/{validations_test.rb → cases/validations_test.rb} +141 -39
  121. data/test/{xml_serialization_test.rb → cases/xml_serialization_test.rb} +12 -12
  122. data/test/config.rb +5 -0
  123. data/test/connections/native_db2/connection.rb +1 -1
  124. data/test/connections/native_firebird/connection.rb +1 -1
  125. data/test/connections/native_frontbase/connection.rb +1 -1
  126. data/test/connections/native_mysql/connection.rb +1 -1
  127. data/test/connections/native_openbase/connection.rb +1 -1
  128. data/test/connections/native_oracle/connection.rb +1 -1
  129. data/test/connections/native_postgresql/connection.rb +1 -3
  130. data/test/connections/native_sqlite/connection.rb +2 -2
  131. data/test/connections/native_sqlite3/connection.rb +2 -2
  132. data/test/connections/native_sqlite3/in_memory_connection.rb +3 -3
  133. data/test/connections/native_sybase/connection.rb +1 -1
  134. data/test/fixtures/author_addresses.yml +5 -0
  135. data/test/fixtures/authors.yml +2 -0
  136. data/test/fixtures/clubs.yml +6 -0
  137. data/test/fixtures/jobs.yml +7 -0
  138. data/test/fixtures/members.yml +4 -0
  139. data/test/fixtures/memberships.yml +20 -0
  140. data/test/fixtures/owners.yml +7 -0
  141. data/test/fixtures/people.yml +4 -1
  142. data/test/fixtures/pets.yml +14 -0
  143. data/test/fixtures/posts.yml +1 -0
  144. data/test/fixtures/price_estimates.yml +7 -0
  145. data/test/fixtures/readers.yml +5 -0
  146. data/test/fixtures/references.yml +17 -0
  147. data/test/fixtures/sponsors.yml +9 -0
  148. data/test/fixtures/subscribers.yml +7 -0
  149. data/test/fixtures/subscriptions.yml +12 -0
  150. data/test/fixtures/taggings.yml +4 -1
  151. data/test/fixtures/topics.yml +22 -2
  152. data/test/fixtures/warehouse-things.yml +3 -0
  153. data/test/{fixtures/migrations_with_decimal → migrations/decimal}/1_give_me_big_numbers.rb +0 -0
  154. data/test/{fixtures/migrations_with_duplicate → migrations/duplicate}/1_people_have_last_names.rb +1 -1
  155. data/test/{fixtures/migrations_with_duplicate → migrations/duplicate}/2_we_need_reminders.rb +1 -1
  156. data/test/{fixtures/migrations_with_duplicate → migrations/duplicate}/3_foo.rb +0 -0
  157. data/test/{fixtures/migrations → migrations/duplicate}/3_innocent_jointable.rb +0 -0
  158. data/test/migrations/duplicate_names/20080507052938_chunky.rb +7 -0
  159. data/test/migrations/duplicate_names/20080507053028_chunky.rb +7 -0
  160. data/test/{fixtures/migrations_with_duplicate → migrations/interleaved/pass_1}/3_innocent_jointable.rb +0 -0
  161. data/test/{fixtures/migrations → migrations/interleaved/pass_2}/1_people_have_last_names.rb +1 -1
  162. data/test/{fixtures/migrations_with_missing_versions/4_innocent_jointable.rb → migrations/interleaved/pass_2/3_innocent_jointable.rb} +0 -0
  163. data/test/{fixtures/migrations_with_missing_versions → migrations/interleaved/pass_3}/1_people_have_last_names.rb +1 -1
  164. data/test/migrations/interleaved/pass_3/2_i_raise_on_down.rb +8 -0
  165. data/test/migrations/interleaved/pass_3/3_innocent_jointable.rb +12 -0
  166. data/test/{fixtures/migrations_with_missing_versions → migrations/missing}/1000_people_have_middle_names.rb +1 -1
  167. data/test/migrations/missing/1_people_have_last_names.rb +9 -0
  168. data/test/{fixtures/migrations_with_missing_versions → migrations/missing}/3_we_need_reminders.rb +1 -1
  169. data/test/migrations/missing/4_innocent_jointable.rb +12 -0
  170. data/test/migrations/valid/1_people_have_last_names.rb +9 -0
  171. data/test/{fixtures/migrations → migrations/valid}/2_we_need_reminders.rb +1 -1
  172. data/test/migrations/valid/3_innocent_jointable.rb +12 -0
  173. data/test/{fixtures → models}/author.rb +28 -4
  174. data/test/{fixtures → models}/auto_id.rb +0 -0
  175. data/test/{fixtures → models}/binary.rb +0 -0
  176. data/test/{fixtures → models}/book.rb +0 -0
  177. data/test/{fixtures → models}/categorization.rb +0 -0
  178. data/test/{fixtures → models}/category.rb +8 -5
  179. data/test/{fixtures → models}/citation.rb +0 -0
  180. data/test/models/club.rb +7 -0
  181. data/test/{fixtures → models}/column_name.rb +0 -0
  182. data/test/{fixtures → models}/comment.rb +5 -3
  183. data/test/{fixtures → models}/company.rb +15 -6
  184. data/test/{fixtures → models}/company_in_module.rb +5 -3
  185. data/test/{fixtures → models}/computer.rb +0 -1
  186. data/test/{fixtures → models}/contact.rb +1 -1
  187. data/test/{fixtures → models}/course.rb +0 -0
  188. data/test/{fixtures → models}/customer.rb +8 -8
  189. data/test/{fixtures → models}/default.rb +0 -0
  190. data/test/{fixtures → models}/developer.rb +14 -10
  191. data/test/{fixtures → models}/edge.rb +0 -0
  192. data/test/{fixtures → models}/entrant.rb +0 -0
  193. data/test/models/guid.rb +2 -0
  194. data/test/{fixtures → models}/item.rb +0 -0
  195. data/test/models/job.rb +5 -0
  196. data/test/{fixtures → models}/joke.rb +0 -0
  197. data/test/{fixtures → models}/keyboard.rb +0 -0
  198. data/test/{fixtures → models}/legacy_thing.rb +0 -0
  199. data/test/{fixtures → models}/matey.rb +0 -0
  200. data/test/models/member.rb +9 -0
  201. data/test/models/membership.rb +9 -0
  202. data/test/{fixtures → models}/minimalistic.rb +0 -0
  203. data/test/{fixtures → models}/mixed_case_monkey.rb +0 -0
  204. data/test/{fixtures → models}/movie.rb +0 -0
  205. data/test/{fixtures → models}/order.rb +2 -2
  206. data/test/models/owner.rb +4 -0
  207. data/test/{fixtures → models}/parrot.rb +0 -0
  208. data/test/models/person.rb +10 -0
  209. data/test/models/pet.rb +4 -0
  210. data/test/models/pirate.rb +9 -0
  211. data/test/{fixtures → models}/post.rb +23 -2
  212. data/test/models/price_estimate.rb +3 -0
  213. data/test/{fixtures → models}/project.rb +1 -0
  214. data/test/{fixtures → models}/reader.rb +0 -0
  215. data/test/models/reference.rb +4 -0
  216. data/test/{fixtures → models}/reply.rb +7 -5
  217. data/test/{fixtures → models}/ship.rb +0 -0
  218. data/test/models/sponsor.rb +4 -0
  219. data/test/{fixtures → models}/subject.rb +0 -0
  220. data/test/{fixtures → models}/subscriber.rb +2 -0
  221. data/test/models/subscription.rb +4 -0
  222. data/test/{fixtures → models}/tag.rb +0 -0
  223. data/test/{fixtures → models}/tagging.rb +0 -0
  224. data/test/{fixtures → models}/task.rb +0 -0
  225. data/test/{fixtures → models}/topic.rb +32 -4
  226. data/test/{fixtures → models}/treasure.rb +2 -0
  227. data/test/{fixtures → models}/vertex.rb +0 -0
  228. data/test/models/warehouse_thing.rb +5 -0
  229. data/test/schema/mysql_specific_schema.rb +12 -0
  230. data/test/schema/postgresql_specific_schema.rb +103 -0
  231. data/test/schema/schema.rb +421 -0
  232. data/test/schema/schema2.rb +6 -0
  233. data/test/schema/sqlite_specific_schema.rb +25 -0
  234. data/test/schema/sqlserver_specific_schema.rb +5 -0
  235. metadata +192 -176
  236. data/test/aaa_create_tables_test.rb +0 -72
  237. data/test/abstract_unit.rb +0 -84
  238. data/test/active_schema_test_mysql.rb +0 -46
  239. data/test/all.sh +0 -8
  240. data/test/association_inheritance_reload.rb +0 -14
  241. data/test/associations_test.rb +0 -2177
  242. data/test/fixtures/bad_fixtures/attr_with_numeric_first_char +0 -1
  243. data/test/fixtures/bad_fixtures/attr_with_spaces +0 -1
  244. data/test/fixtures/bad_fixtures/blank_line +0 -3
  245. data/test/fixtures/bad_fixtures/duplicate_attributes +0 -3
  246. data/test/fixtures/bad_fixtures/missing_value +0 -1
  247. data/test/fixtures/db_definitions/db2.drop.sql +0 -33
  248. data/test/fixtures/db_definitions/db2.sql +0 -235
  249. data/test/fixtures/db_definitions/db22.drop.sql +0 -2
  250. data/test/fixtures/db_definitions/db22.sql +0 -5
  251. data/test/fixtures/db_definitions/firebird.drop.sql +0 -65
  252. data/test/fixtures/db_definitions/firebird.sql +0 -310
  253. data/test/fixtures/db_definitions/firebird2.drop.sql +0 -2
  254. data/test/fixtures/db_definitions/firebird2.sql +0 -6
  255. data/test/fixtures/db_definitions/frontbase.drop.sql +0 -33
  256. data/test/fixtures/db_definitions/frontbase.sql +0 -273
  257. data/test/fixtures/db_definitions/frontbase2.drop.sql +0 -1
  258. data/test/fixtures/db_definitions/frontbase2.sql +0 -4
  259. data/test/fixtures/db_definitions/openbase.drop.sql +0 -2
  260. data/test/fixtures/db_definitions/openbase.sql +0 -318
  261. data/test/fixtures/db_definitions/openbase2.drop.sql +0 -2
  262. data/test/fixtures/db_definitions/openbase2.sql +0 -7
  263. data/test/fixtures/db_definitions/oracle.drop.sql +0 -67
  264. data/test/fixtures/db_definitions/oracle.sql +0 -330
  265. data/test/fixtures/db_definitions/oracle2.drop.sql +0 -2
  266. data/test/fixtures/db_definitions/oracle2.sql +0 -6
  267. data/test/fixtures/db_definitions/postgresql.drop.sql +0 -44
  268. data/test/fixtures/db_definitions/postgresql.sql +0 -292
  269. data/test/fixtures/db_definitions/postgresql2.drop.sql +0 -2
  270. data/test/fixtures/db_definitions/postgresql2.sql +0 -4
  271. data/test/fixtures/db_definitions/schema.rb +0 -354
  272. data/test/fixtures/db_definitions/schema2.rb +0 -11
  273. data/test/fixtures/db_definitions/sqlite.drop.sql +0 -33
  274. data/test/fixtures/db_definitions/sqlite.sql +0 -219
  275. data/test/fixtures/db_definitions/sqlite2.drop.sql +0 -2
  276. data/test/fixtures/db_definitions/sqlite2.sql +0 -5
  277. data/test/fixtures/db_definitions/sybase.drop.sql +0 -35
  278. data/test/fixtures/db_definitions/sybase.sql +0 -222
  279. data/test/fixtures/db_definitions/sybase2.drop.sql +0 -4
  280. data/test/fixtures/db_definitions/sybase2.sql +0 -5
  281. data/test/fixtures/developers_projects/david_action_controller +0 -3
  282. data/test/fixtures/developers_projects/david_active_record +0 -3
  283. data/test/fixtures/developers_projects/jamis_active_record +0 -2
  284. data/test/fixtures/person.rb +0 -4
  285. data/test/fixtures/pirate.rb +0 -5
  286. data/test/fixtures/subscribers/first +0 -2
  287. data/test/fixtures/subscribers/second +0 -2
  288. data/test/schema_dumper_test.rb +0 -131
  289. data/test/schema_test_postgresql.rb +0 -64
@@ -1,72 +0,0 @@
1
- # The filename begins with "aaa" to ensure this is the first test.
2
- require 'abstract_unit'
3
-
4
- class AAACreateTablesTest < Test::Unit::TestCase
5
- self.use_transactional_fixtures = false
6
-
7
- def setup
8
- @base_path = "#{File.dirname(__FILE__)}/fixtures/db_definitions"
9
- end
10
-
11
- def test_drop_and_create_main_tables
12
- recreate ActiveRecord::Base unless use_migrations?
13
- assert true
14
- end
15
-
16
- def test_load_schema
17
- if ActiveRecord::Base.connection.supports_migrations?
18
- eval(File.read("#{File.dirname(__FILE__)}/fixtures/db_definitions/schema.rb"))
19
- else
20
- recreate ActiveRecord::Base, '3'
21
- end
22
- assert true
23
- end
24
-
25
- def test_drop_and_create_courses_table
26
- if Course.connection.supports_migrations?
27
- eval(File.read("#{File.dirname(__FILE__)}/fixtures/db_definitions/schema2.rb"))
28
- end
29
- recreate Course, '2' unless use_migrations_for_courses?
30
- assert true
31
- end
32
-
33
- private
34
- def use_migrations?
35
- unittest_sql_filename = ActiveRecord::Base.connection.adapter_name.downcase + ".sql"
36
- not File.exist? "#{@base_path}/#{unittest_sql_filename}"
37
- end
38
-
39
- def use_migrations_for_courses?
40
- unittest2_sql_filename = ActiveRecord::Base.connection.adapter_name.downcase + "2.sql"
41
- not File.exist? "#{@base_path}/#{unittest2_sql_filename}"
42
- end
43
-
44
- def recreate(base, suffix = nil)
45
- connection = base.connection
46
- adapter_name = connection.adapter_name.downcase + suffix.to_s
47
- execute_sql_file "#{@base_path}/#{adapter_name}.drop.sql", connection
48
- execute_sql_file "#{@base_path}/#{adapter_name}.sql", connection
49
- end
50
-
51
- def execute_sql_file(path, connection)
52
- # OpenBase has a different format for sql files
53
- if current_adapter?(:OpenBaseAdapter) then
54
- File.read(path).split("go").each_with_index do |sql, i|
55
- begin
56
- # OpenBase does not support comments embedded in sql
57
- connection.execute(sql,"SQL statement ##{i}") unless sql.blank?
58
- rescue ActiveRecord::StatementInvalid
59
- #$stderr.puts "warning: #{$!}"
60
- end
61
- end
62
- else
63
- File.read(path).split(';').each_with_index do |sql, i|
64
- begin
65
- connection.execute("\n\n-- statement ##{i}\n#{sql}\n") unless sql.blank?
66
- rescue ActiveRecord::StatementInvalid
67
- #$stderr.puts "warning: #{$!}"
68
- end
69
- end
70
- end
71
- end
72
- end
@@ -1,84 +0,0 @@
1
- $:.unshift(File.dirname(__FILE__) + '/../lib')
2
- $:.unshift(File.dirname(__FILE__) + '/../../activesupport/lib')
3
-
4
- require 'test/unit'
5
- require 'active_record'
6
- require 'active_record/fixtures'
7
- require 'active_support/test_case'
8
- require 'connection'
9
-
10
- # Show backtraces for deprecated behavior for quicker cleanup.
11
- ActiveSupport::Deprecation.debug = true
12
-
13
-
14
- QUOTED_TYPE = ActiveRecord::Base.connection.quote_column_name('type') unless Object.const_defined?(:QUOTED_TYPE)
15
-
16
- class Test::Unit::TestCase #:nodoc:
17
- self.fixture_path = File.dirname(__FILE__) + "/fixtures/"
18
- self.use_instantiated_fixtures = false
19
- self.use_transactional_fixtures = (ENV['AR_NO_TX_FIXTURES'] != "yes")
20
-
21
- def create_fixtures(*table_names, &block)
22
- Fixtures.create_fixtures(File.dirname(__FILE__) + "/fixtures/", table_names, {}, &block)
23
- end
24
-
25
- def assert_date_from_db(expected, actual, message = nil)
26
- # SQL Server doesn't have a separate column type just for dates,
27
- # so the time is in the string and incorrectly formatted
28
- if current_adapter?(:SQLServerAdapter)
29
- assert_equal expected.strftime("%Y/%m/%d 00:00:00"), actual.strftime("%Y/%m/%d 00:00:00")
30
- elsif current_adapter?(:SybaseAdapter)
31
- assert_equal expected.to_s, actual.to_date.to_s, message
32
- else
33
- assert_equal expected.to_s, actual.to_s, message
34
- end
35
- end
36
-
37
- def assert_queries(num = 1)
38
- $query_count = 0
39
- yield
40
- ensure
41
- assert_equal num, $query_count, "#{$query_count} instead of #{num} queries were executed."
42
- end
43
-
44
- def assert_no_queries(&block)
45
- assert_queries(0, &block)
46
- end
47
- end
48
-
49
- def current_adapter?(*types)
50
- types.any? do |type|
51
- ActiveRecord::ConnectionAdapters.const_defined?(type) &&
52
- ActiveRecord::Base.connection.is_a?(ActiveRecord::ConnectionAdapters.const_get(type))
53
- end
54
- end
55
-
56
- def uses_mocha(test_name)
57
- require 'rubygems'
58
- require 'mocha'
59
- yield
60
- rescue LoadError
61
- $stderr.puts "Skipping #{test_name} tests. `gem install mocha` and try again."
62
- end
63
-
64
- ActiveRecord::Base.connection.class.class_eval do
65
- unless defined? IGNORED_SQL
66
- IGNORED_SQL = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/]
67
-
68
- def execute_with_counting(sql, name = nil, &block)
69
- $query_count ||= 0
70
- $query_count += 1 unless IGNORED_SQL.any? { |r| sql =~ r }
71
- execute_without_counting(sql, name, &block)
72
- end
73
-
74
- alias_method_chain :execute, :counting
75
- end
76
- end
77
-
78
- # Make with_scope public for tests
79
- class << ActiveRecord::Base
80
- public :with_scope, :with_exclusive_scope
81
- end
82
-
83
- #ActiveRecord::Base.logger = Logger.new(STDOUT)
84
- #ActiveRecord::Base.colorize_logging = false
@@ -1,46 +0,0 @@
1
- require 'abstract_unit'
2
-
3
- class ActiveSchemaTest < Test::Unit::TestCase
4
- def setup
5
- ActiveRecord::ConnectionAdapters::MysqlAdapter.class_eval do
6
- alias_method :execute_without_stub, :execute
7
- def execute(sql, name = nil) return sql end
8
- end
9
- end
10
-
11
- def teardown
12
- ActiveRecord::ConnectionAdapters::MysqlAdapter.class_eval do
13
- remove_method :execute
14
- alias_method :execute, :execute_without_stub
15
- end
16
- end
17
-
18
- def test_drop_table
19
- assert_equal "DROP TABLE `people`", drop_table(:people)
20
- end
21
-
22
- if current_adapter?(:MysqlAdapter)
23
- def test_create_mysql_database_with_encoding
24
- assert_equal "CREATE DATABASE `matt` DEFAULT CHARACTER SET `utf8`", create_database(:matt)
25
- assert_equal "CREATE DATABASE `aimonetti` DEFAULT CHARACTER SET `latin1`", create_database(:aimonetti, {:charset => 'latin1'})
26
- assert_equal "CREATE DATABASE `matt_aimonetti` DEFAULT CHARACTER SET `big5` COLLATE `big5_chinese_ci`", create_database(:matt_aimonetti, {:charset => :big5, :collation => :big5_chinese_ci})
27
- end
28
- end
29
-
30
- def test_add_column
31
- assert_equal "ALTER TABLE `people` ADD `last_name` varchar(255)", add_column(:people, :last_name, :string)
32
- end
33
-
34
- def test_add_column_with_limit
35
- assert_equal "ALTER TABLE `people` ADD `key` varchar(32)", add_column(:people, :key, :string, :limit => 32)
36
- end
37
-
38
- def test_drop_table_with_specific_database
39
- assert_equal "DROP TABLE `otherdb`.`people`", drop_table('otherdb.people')
40
- end
41
-
42
- private
43
- def method_missing(method_symbol, *arguments)
44
- ActiveRecord::Base.connection.send(method_symbol, *arguments)
45
- end
46
- end
@@ -1,8 +0,0 @@
1
- #!/bin/sh
2
-
3
- if [ -z "$1" ]; then
4
- echo "Usage: $0 <database>" 1>&2
5
- exit 1
6
- fi
7
-
8
- ruby -I connections/native_$1 -e 'Dir["**/*_test.rb"].each { |path| require path }'
@@ -1,14 +0,0 @@
1
- require 'abstract_unit'
2
- require 'fixtures/company'
3
-
4
- class AssociationInheritanceReloadTest < Test::Unit::TestCase
5
- fixtures :companies
6
-
7
- def test_set_attributes
8
- assert_equal ["errors.add_on_empty('name', \"can't be empty\")"], Firm.read_inheritable_attribute("validate"), "Second run"
9
- # ActiveRecord::Base.reset_column_information_and_inheritable_attributes_for_all_subclasses
10
- remove_subclass_of(ActiveRecord::Base)
11
- load 'fixtures/company.rb'
12
- assert_equal ["errors.add_on_empty('name', \"can't be empty\")"], Firm.read_inheritable_attribute("validate"), "Second run"
13
- end
14
- end
@@ -1,2177 +0,0 @@
1
- require 'abstract_unit'
2
- require 'fixtures/developer'
3
- require 'fixtures/project'
4
- require 'fixtures/company'
5
- require 'fixtures/topic'
6
- require 'fixtures/reply'
7
- require 'fixtures/computer'
8
- require 'fixtures/customer'
9
- require 'fixtures/order'
10
- require 'fixtures/categorization'
11
- require 'fixtures/category'
12
- require 'fixtures/post'
13
- require 'fixtures/author'
14
- require 'fixtures/comment'
15
- require 'fixtures/tag'
16
- require 'fixtures/tagging'
17
- require 'fixtures/person'
18
- require 'fixtures/reader'
19
-
20
- class AssociationsTest < Test::Unit::TestCase
21
- fixtures :accounts, :companies, :developers, :projects, :developers_projects,
22
- :computers
23
-
24
- def test_bad_collection_keys
25
- assert_raise(ArgumentError, 'ActiveRecord should have barked on bad collection keys') do
26
- Class.new(ActiveRecord::Base).has_many(:wheels, :name => 'wheels')
27
- end
28
- end
29
-
30
- def test_should_construct_new_finder_sql_after_create
31
- person = Person.new
32
- assert_equal [], person.readers.find(:all)
33
- person.save!
34
- reader = Reader.create! :person => person, :post => Post.new(:title => "foo", :body => "bar")
35
- assert_equal [reader], person.readers.find(:all)
36
- end
37
-
38
- def test_force_reload
39
- firm = Firm.new("name" => "A New Firm, Inc")
40
- firm.save
41
- firm.clients.each {|c|} # forcing to load all clients
42
- assert firm.clients.empty?, "New firm shouldn't have client objects"
43
- assert_equal 0, firm.clients.size, "New firm should have 0 clients"
44
-
45
- client = Client.new("name" => "TheClient.com", "firm_id" => firm.id)
46
- client.save
47
-
48
- assert firm.clients.empty?, "New firm should have cached no client objects"
49
- assert_equal 0, firm.clients.size, "New firm should have cached 0 clients count"
50
-
51
- assert !firm.clients(true).empty?, "New firm should have reloaded client objects"
52
- assert_equal 1, firm.clients(true).size, "New firm should have reloaded clients count"
53
- end
54
-
55
- def test_storing_in_pstore
56
- require "tmpdir"
57
- store_filename = File.join(Dir.tmpdir, "ar-pstore-association-test")
58
- File.delete(store_filename) if File.exist?(store_filename)
59
- require "pstore"
60
- apple = Firm.create("name" => "Apple")
61
- natural = Client.new("name" => "Natural Company")
62
- apple.clients << natural
63
-
64
- db = PStore.new(store_filename)
65
- db.transaction do
66
- db["apple"] = apple
67
- end
68
-
69
- db = PStore.new(store_filename)
70
- db.transaction do
71
- assert_equal "Natural Company", db["apple"].clients.first.name
72
- end
73
- end
74
- end
75
-
76
- class AssociationProxyTest < Test::Unit::TestCase
77
- fixtures :authors, :posts, :categorizations, :categories, :developers, :projects, :developers_projects
78
-
79
- def test_proxy_accessors
80
- welcome = posts(:welcome)
81
- assert_equal welcome, welcome.author.proxy_owner
82
- assert_equal welcome.class.reflect_on_association(:author), welcome.author.proxy_reflection
83
- welcome.author.class # force load target
84
- assert_equal welcome.author, welcome.author.proxy_target
85
-
86
- david = authors(:david)
87
- assert_equal david, david.posts.proxy_owner
88
- assert_equal david.class.reflect_on_association(:posts), david.posts.proxy_reflection
89
- david.posts.first # force load target
90
- assert_equal david.posts, david.posts.proxy_target
91
-
92
- assert_equal david, david.posts_with_extension.testing_proxy_owner
93
- assert_equal david.class.reflect_on_association(:posts_with_extension), david.posts_with_extension.testing_proxy_reflection
94
- david.posts_with_extension.first # force load target
95
- assert_equal david.posts_with_extension, david.posts_with_extension.testing_proxy_target
96
- end
97
-
98
- def test_push_does_not_load_target
99
- david = authors(:david)
100
-
101
- david.posts << (post = Post.new(:title => "New on Edge", :body => "More cool stuff!"))
102
- assert !david.posts.loaded?
103
- assert david.posts.include?(post)
104
- end
105
-
106
- def test_push_has_many_through_does_not_load_target
107
- david = authors(:david)
108
-
109
- david.categories << categories(:technology)
110
- assert !david.categories.loaded?
111
- assert david.categories.include?(categories(:technology))
112
- end
113
-
114
- def test_push_followed_by_save_does_not_load_target
115
- david = authors(:david)
116
-
117
- david.posts << (post = Post.new(:title => "New on Edge", :body => "More cool stuff!"))
118
- assert !david.posts.loaded?
119
- david.save
120
- assert !david.posts.loaded?
121
- assert david.posts.include?(post)
122
- end
123
-
124
- def test_push_does_not_lose_additions_to_new_record
125
- josh = Author.new(:name => "Josh")
126
- josh.posts << Post.new(:title => "New on Edge", :body => "More cool stuff!")
127
- assert josh.posts.loaded?
128
- assert_equal 1, josh.posts.size
129
- end
130
-
131
- def test_save_on_parent_does_not_load_target
132
- david = developers(:david)
133
-
134
- assert !david.projects.loaded?
135
- david.update_attribute(:created_at, Time.now)
136
- assert !david.projects.loaded?
137
- end
138
-
139
- def test_save_on_parent_saves_children
140
- developer = Developer.create :name => "Bryan", :salary => 50_000
141
- assert_equal 1, developer.reload.audit_logs.size
142
- end
143
-
144
- def test_failed_reload_returns_nil
145
- p = setup_dangling_association
146
- assert_nil p.author.reload
147
- end
148
-
149
- def test_failed_reset_returns_nil
150
- p = setup_dangling_association
151
- assert_nil p.author.reset
152
- end
153
-
154
- def test_reload_returns_assocition
155
- david = developers(:david)
156
- assert_nothing_raised do
157
- assert_equal david.projects, david.projects.reload.reload
158
- end
159
- end
160
-
161
- def setup_dangling_association
162
- josh = Author.create(:name => "Josh")
163
- p = Post.create(:title => "New on Edge", :body => "More cool stuff!", :author => josh)
164
- josh.destroy
165
- p
166
- end
167
- end
168
-
169
- class HasOneAssociationsTest < Test::Unit::TestCase
170
- fixtures :accounts, :companies, :developers, :projects, :developers_projects
171
-
172
- def setup
173
- Account.destroyed_account_ids.clear
174
- end
175
-
176
- def test_has_one
177
- assert_equal companies(:first_firm).account, Account.find(1)
178
- assert_equal Account.find(1).credit_limit, companies(:first_firm).account.credit_limit
179
- end
180
-
181
- def test_has_one_cache_nils
182
- firm = companies(:another_firm)
183
- assert_queries(1) { assert_nil firm.account }
184
- assert_queries(0) { assert_nil firm.account }
185
-
186
- firms = Firm.find(:all, :include => :account)
187
- assert_queries(0) { firms.each(&:account) }
188
- end
189
-
190
- def test_can_marshal_has_one_association_with_nil_target
191
- firm = Firm.new
192
- assert_nothing_raised do
193
- assert_equal firm.attributes, Marshal.load(Marshal.dump(firm)).attributes
194
- end
195
-
196
- firm.account
197
- assert_nothing_raised do
198
- assert_equal firm.attributes, Marshal.load(Marshal.dump(firm)).attributes
199
- end
200
- end
201
-
202
- def test_proxy_assignment
203
- company = companies(:first_firm)
204
- assert_nothing_raised { company.account = company.account }
205
- end
206
-
207
- def test_triple_equality
208
- assert Account === companies(:first_firm).account
209
- assert companies(:first_firm).account === Account
210
- end
211
-
212
- def test_type_mismatch
213
- assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).account = 1 }
214
- assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).account = Project.find(1) }
215
- end
216
-
217
- def test_natural_assignment
218
- apple = Firm.create("name" => "Apple")
219
- citibank = Account.create("credit_limit" => 10)
220
- apple.account = citibank
221
- assert_equal apple.id, citibank.firm_id
222
- end
223
-
224
- def test_natural_assignment_to_nil
225
- old_account_id = companies(:first_firm).account.id
226
- companies(:first_firm).account = nil
227
- companies(:first_firm).save
228
- assert_nil companies(:first_firm).account
229
- # account is dependent, therefore is destroyed when reference to owner is lost
230
- assert_raises(ActiveRecord::RecordNotFound) { Account.find(old_account_id) }
231
- end
232
-
233
- def test_assignment_without_replacement
234
- apple = Firm.create("name" => "Apple")
235
- citibank = Account.create("credit_limit" => 10)
236
- apple.account = citibank
237
- assert_equal apple.id, citibank.firm_id
238
-
239
- hsbc = apple.build_account({ :credit_limit => 20}, false)
240
- assert_equal apple.id, hsbc.firm_id
241
- hsbc.save
242
- assert_equal apple.id, citibank.firm_id
243
-
244
- nykredit = apple.create_account({ :credit_limit => 30}, false)
245
- assert_equal apple.id, nykredit.firm_id
246
- assert_equal apple.id, citibank.firm_id
247
- assert_equal apple.id, hsbc.firm_id
248
- end
249
-
250
- def test_assignment_without_replacement_on_create
251
- apple = Firm.create("name" => "Apple")
252
- citibank = Account.create("credit_limit" => 10)
253
- apple.account = citibank
254
- assert_equal apple.id, citibank.firm_id
255
-
256
- hsbc = apple.create_account({:credit_limit => 10}, false)
257
- assert_equal apple.id, hsbc.firm_id
258
- hsbc.save
259
- assert_equal apple.id, citibank.firm_id
260
- end
261
-
262
- def test_dependence
263
- num_accounts = Account.count
264
-
265
- firm = Firm.find(1)
266
- assert !firm.account.nil?
267
- account_id = firm.account.id
268
- assert_equal [], Account.destroyed_account_ids[firm.id]
269
-
270
- firm.destroy
271
- assert_equal num_accounts - 1, Account.count
272
- assert_equal [account_id], Account.destroyed_account_ids[firm.id]
273
- end
274
-
275
- def test_exclusive_dependence
276
- num_accounts = Account.count
277
-
278
- firm = ExclusivelyDependentFirm.find(9)
279
- assert !firm.account.nil?
280
- account_id = firm.account.id
281
- assert_equal [], Account.destroyed_account_ids[firm.id]
282
-
283
- firm.destroy
284
- assert_equal num_accounts - 1, Account.count
285
- assert_equal [], Account.destroyed_account_ids[firm.id]
286
- end
287
-
288
- def test_dependence_with_nil_associate
289
- firm = DependentFirm.new(:name => 'nullify')
290
- firm.save!
291
- assert_nothing_raised { firm.destroy }
292
- end
293
-
294
- def test_succesful_build_association
295
- firm = Firm.new("name" => "GlobalMegaCorp")
296
- firm.save
297
-
298
- account = firm.build_account("credit_limit" => 1000)
299
- assert account.save
300
- assert_equal account, firm.account
301
- end
302
-
303
- def test_failing_build_association
304
- firm = Firm.new("name" => "GlobalMegaCorp")
305
- firm.save
306
-
307
- account = firm.build_account
308
- assert !account.save
309
- assert_equal "can't be empty", account.errors.on("credit_limit")
310
- end
311
-
312
- def test_build_association_twice_without_saving_affects_nothing
313
- count_of_account = Account.count
314
- firm = Firm.find(:first)
315
- account1 = firm.build_account("credit_limit" => 1000)
316
- account2 = firm.build_account("credit_limit" => 2000)
317
-
318
- assert_equal count_of_account, Account.count
319
- end
320
-
321
- def test_create_association
322
- firm = Firm.create(:name => "GlobalMegaCorp")
323
- account = firm.create_account(:credit_limit => 1000)
324
- assert_equal account, firm.reload.account
325
- end
326
-
327
- def test_build
328
- firm = Firm.new("name" => "GlobalMegaCorp")
329
- firm.save
330
-
331
- firm.account = account = Account.new("credit_limit" => 1000)
332
- assert_equal account, firm.account
333
- assert account.save
334
- assert_equal account, firm.account
335
- end
336
-
337
- def test_build_before_child_saved
338
- firm = Firm.find(1)
339
-
340
- account = firm.account.build("credit_limit" => 1000)
341
- assert_equal account, firm.account
342
- assert account.new_record?
343
- assert firm.save
344
- assert_equal account, firm.account
345
- assert !account.new_record?
346
- end
347
-
348
- def test_build_before_either_saved
349
- firm = Firm.new("name" => "GlobalMegaCorp")
350
-
351
- firm.account = account = Account.new("credit_limit" => 1000)
352
- assert_equal account, firm.account
353
- assert account.new_record?
354
- assert firm.save
355
- assert_equal account, firm.account
356
- assert !account.new_record?
357
- end
358
-
359
- def test_failing_build_association
360
- firm = Firm.new("name" => "GlobalMegaCorp")
361
- firm.save
362
-
363
- firm.account = account = Account.new
364
- assert_equal account, firm.account
365
- assert !account.save
366
- assert_equal account, firm.account
367
- assert_equal "can't be empty", account.errors.on("credit_limit")
368
- end
369
-
370
- def test_create
371
- firm = Firm.new("name" => "GlobalMegaCorp")
372
- firm.save
373
- firm.account = account = Account.create("credit_limit" => 1000)
374
- assert_equal account, firm.account
375
- end
376
-
377
- def test_create_before_save
378
- firm = Firm.new("name" => "GlobalMegaCorp")
379
- firm.account = account = Account.create("credit_limit" => 1000)
380
- assert_equal account, firm.account
381
- end
382
-
383
- def test_dependence_with_missing_association
384
- Account.destroy_all
385
- firm = Firm.find(1)
386
- assert firm.account.nil?
387
- firm.destroy
388
- end
389
-
390
- def test_dependence_with_missing_association_and_nullify
391
- Account.destroy_all
392
- firm = DependentFirm.find(:first)
393
- assert firm.account.nil?
394
- firm.destroy
395
- end
396
-
397
- def test_assignment_before_parent_saved
398
- firm = Firm.new("name" => "GlobalMegaCorp")
399
- firm.account = a = Account.find(1)
400
- assert firm.new_record?
401
- assert_equal a, firm.account
402
- assert firm.save
403
- assert_equal a, firm.account
404
- assert_equal a, firm.account(true)
405
- end
406
-
407
- def test_finding_with_interpolated_condition
408
- firm = Firm.find(:first)
409
- superior = firm.clients.create(:name => 'SuperiorCo')
410
- superior.rating = 10
411
- superior.save
412
- assert_equal 10, firm.clients_with_interpolated_conditions.first.rating
413
- end
414
-
415
- def test_assignment_before_child_saved
416
- firm = Firm.find(1)
417
- firm.account = a = Account.new("credit_limit" => 1000)
418
- assert !a.new_record?
419
- assert_equal a, firm.account
420
- assert_equal a, firm.account
421
- assert_equal a, firm.account(true)
422
- end
423
-
424
- def test_assignment_before_either_saved
425
- firm = Firm.new("name" => "GlobalMegaCorp")
426
- firm.account = a = Account.new("credit_limit" => 1000)
427
- assert firm.new_record?
428
- assert a.new_record?
429
- assert_equal a, firm.account
430
- assert firm.save
431
- assert !firm.new_record?
432
- assert !a.new_record?
433
- assert_equal a, firm.account
434
- assert_equal a, firm.account(true)
435
- end
436
-
437
- def test_not_resaved_when_unchanged
438
- firm = Firm.find(:first, :include => :account)
439
- assert_queries(1) { firm.save! }
440
-
441
- firm = Firm.find(:first)
442
- firm.account = Account.find(:first)
443
- assert_queries(1) { firm.save! }
444
-
445
- firm = Firm.find(:first).clone
446
- firm.account = Account.find(:first)
447
- assert_queries(2) { firm.save! }
448
-
449
- firm = Firm.find(:first).clone
450
- firm.account = Account.find(:first).clone
451
- assert_queries(2) { firm.save! }
452
- end
453
-
454
- def test_save_still_works_after_accessing_nil_has_one
455
- jp = Company.new :name => 'Jaded Pixel'
456
- jp.dummy_account.nil?
457
-
458
- assert_nothing_raised do
459
- jp.save!
460
- end
461
- end
462
-
463
- end
464
-
465
-
466
- class HasManyAssociationsTest < Test::Unit::TestCase
467
- fixtures :accounts, :companies, :developers, :projects,
468
- :developers_projects, :topics, :authors, :comments
469
-
470
- def setup
471
- Client.destroyed_client_ids.clear
472
- end
473
-
474
- def force_signal37_to_load_all_clients_of_firm
475
- companies(:first_firm).clients_of_firm.each {|f| }
476
- end
477
-
478
- def test_counting_with_counter_sql
479
- assert_equal 2, Firm.find(:first).clients.count
480
- end
481
-
482
- def test_counting
483
- assert_equal 2, Firm.find(:first).plain_clients.count
484
- end
485
-
486
- def test_counting_with_single_conditions
487
- assert_equal 2, Firm.find(:first).plain_clients.count(:conditions => '1=1')
488
- end
489
-
490
- def test_counting_with_single_hash
491
- assert_equal 2, Firm.find(:first).plain_clients.count(:conditions => '1=1')
492
- end
493
-
494
- def test_counting_with_column_name_and_hash
495
- assert_equal 2, Firm.find(:first).plain_clients.count(:all, :conditions => '1=1')
496
- end
497
-
498
- def test_finding
499
- assert_equal 2, Firm.find(:first).clients.length
500
- end
501
-
502
- def test_find_many_with_merged_options
503
- assert_equal 1, companies(:first_firm).limited_clients.size
504
- assert_equal 1, companies(:first_firm).limited_clients.find(:all).size
505
- assert_equal 2, companies(:first_firm).limited_clients.find(:all, :limit => nil).size
506
- end
507
-
508
- def test_dynamic_find_should_respect_association_order
509
- assert_equal companies(:second_client), companies(:first_firm).clients_sorted_desc.find(:first, :conditions => "type = 'Client'")
510
- assert_equal companies(:second_client), companies(:first_firm).clients_sorted_desc.find_by_type('Client')
511
- end
512
-
513
- def test_dynamic_find_order_should_override_association_order
514
- assert_equal companies(:first_client), companies(:first_firm).clients_sorted_desc.find(:first, :conditions => "type = 'Client'", :order => 'id')
515
- assert_equal companies(:first_client), companies(:first_firm).clients_sorted_desc.find_by_type('Client', :order => 'id')
516
- end
517
-
518
- def test_dynamic_find_all_should_respect_association_order
519
- assert_equal [companies(:second_client), companies(:first_client)], companies(:first_firm).clients_sorted_desc.find(:all, :conditions => "type = 'Client'")
520
- assert_equal [companies(:second_client), companies(:first_client)], companies(:first_firm).clients_sorted_desc.find_all_by_type('Client')
521
- end
522
-
523
- def test_dynamic_find_all_order_should_override_association_order
524
- assert_equal [companies(:first_client), companies(:second_client)], companies(:first_firm).clients_sorted_desc.find(:all, :conditions => "type = 'Client'", :order => 'id')
525
- assert_equal [companies(:first_client), companies(:second_client)], companies(:first_firm).clients_sorted_desc.find_all_by_type('Client', :order => 'id')
526
- end
527
-
528
- def test_dynamic_find_all_should_respect_association_limit
529
- assert_equal 1, companies(:first_firm).limited_clients.find(:all, :conditions => "type = 'Client'").length
530
- assert_equal 1, companies(:first_firm).limited_clients.find_all_by_type('Client').length
531
- end
532
-
533
- def test_dynamic_find_all_limit_should_override_association_limit
534
- assert_equal 2, companies(:first_firm).limited_clients.find(:all, :conditions => "type = 'Client'", :limit => 9_000).length
535
- assert_equal 2, companies(:first_firm).limited_clients.find_all_by_type('Client', :limit => 9_000).length
536
- end
537
-
538
- def test_triple_equality
539
- assert !(Array === Firm.find(:first).clients)
540
- assert Firm.find(:first).clients === Array
541
- end
542
-
543
- def test_finding_default_orders
544
- assert_equal "Summit", Firm.find(:first).clients.first.name
545
- end
546
-
547
- def test_finding_with_different_class_name_and_order
548
- assert_equal "Microsoft", Firm.find(:first).clients_sorted_desc.first.name
549
- end
550
-
551
- def test_finding_with_foreign_key
552
- assert_equal "Microsoft", Firm.find(:first).clients_of_firm.first.name
553
- end
554
-
555
- def test_finding_with_condition
556
- assert_equal "Microsoft", Firm.find(:first).clients_like_ms.first.name
557
- end
558
-
559
- def test_finding_with_condition_hash
560
- assert_equal "Microsoft", Firm.find(:first).clients_like_ms_with_hash_conditions.first.name
561
- end
562
-
563
- def test_finding_using_sql
564
- firm = Firm.find(:first)
565
- first_client = firm.clients_using_sql.first
566
- assert_not_nil first_client
567
- assert_equal "Microsoft", first_client.name
568
- assert_equal 1, firm.clients_using_sql.size
569
- assert_equal 1, Firm.find(:first).clients_using_sql.size
570
- end
571
-
572
- def test_counting_using_sql
573
- assert_equal 1, Firm.find(:first).clients_using_counter_sql.size
574
- assert Firm.find(:first).clients_using_counter_sql.any?
575
- assert_equal 0, Firm.find(:first).clients_using_zero_counter_sql.size
576
- assert !Firm.find(:first).clients_using_zero_counter_sql.any?
577
- end
578
-
579
- def test_counting_non_existant_items_using_sql
580
- assert_equal 0, Firm.find(:first).no_clients_using_counter_sql.size
581
- end
582
-
583
- def test_belongs_to_sanity
584
- c = Client.new
585
- assert_nil c.firm
586
-
587
- if c.firm
588
- assert false, "belongs_to failed if check"
589
- end
590
-
591
- unless c.firm
592
- else
593
- assert false, "belongs_to failed unless check"
594
- end
595
- end
596
-
597
- def test_find_ids
598
- firm = Firm.find(:first)
599
-
600
- assert_raises(ActiveRecord::RecordNotFound) { firm.clients.find }
601
-
602
- client = firm.clients.find(2)
603
- assert_kind_of Client, client
604
-
605
- client_ary = firm.clients.find([2])
606
- assert_kind_of Array, client_ary
607
- assert_equal client, client_ary.first
608
-
609
- client_ary = firm.clients.find(2, 3)
610
- assert_kind_of Array, client_ary
611
- assert_equal 2, client_ary.size
612
- assert_equal client, client_ary.first
613
-
614
- assert_raises(ActiveRecord::RecordNotFound) { firm.clients.find(2, 99) }
615
- end
616
-
617
- def test_find_string_ids_when_using_finder_sql
618
- firm = Firm.find(:first)
619
-
620
- client = firm.clients_using_finder_sql.find("2")
621
- assert_kind_of Client, client
622
-
623
- client_ary = firm.clients_using_finder_sql.find(["2"])
624
- assert_kind_of Array, client_ary
625
- assert_equal client, client_ary.first
626
-
627
- client_ary = firm.clients_using_finder_sql.find("2", "3")
628
- assert_kind_of Array, client_ary
629
- assert_equal 2, client_ary.size
630
- assert client_ary.include?(client)
631
- end
632
-
633
- def test_find_all
634
- firm = Firm.find(:first)
635
- assert_equal 2, firm.clients.find(:all, :conditions => "#{QUOTED_TYPE} = 'Client'").length
636
- assert_equal 1, firm.clients.find(:all, :conditions => "name = 'Summit'").length
637
- end
638
-
639
- def test_find_all_sanitized
640
- firm = Firm.find(:first)
641
- summit = firm.clients.find(:all, :conditions => "name = 'Summit'")
642
- assert_equal summit, firm.clients.find(:all, :conditions => ["name = ?", "Summit"])
643
- assert_equal summit, firm.clients.find(:all, :conditions => ["name = :name", { :name => "Summit" }])
644
- end
645
-
646
- def test_find_first
647
- firm = Firm.find(:first)
648
- client2 = Client.find(2)
649
- assert_equal firm.clients.first, firm.clients.find(:first)
650
- assert_equal client2, firm.clients.find(:first, :conditions => "#{QUOTED_TYPE} = 'Client'")
651
- end
652
-
653
- def test_find_first_sanitized
654
- firm = Firm.find(:first)
655
- client2 = Client.find(2)
656
- assert_equal client2, firm.clients.find(:first, :conditions => ["#{QUOTED_TYPE} = ?", 'Client'])
657
- assert_equal client2, firm.clients.find(:first, :conditions => ["#{QUOTED_TYPE} = :type", { :type => 'Client' }])
658
- end
659
-
660
- def test_find_in_collection
661
- assert_equal Client.find(2).name, companies(:first_firm).clients.find(2).name
662
- assert_raises(ActiveRecord::RecordNotFound) { companies(:first_firm).clients.find(6) }
663
- end
664
-
665
- def test_find_grouped
666
- all_clients_of_firm1 = Client.find(:all, :conditions => "firm_id = 1")
667
- grouped_clients_of_firm1 = Client.find(:all, :conditions => "firm_id = 1", :group => "firm_id", :select => 'firm_id, count(id) as clients_count')
668
- assert_equal 2, all_clients_of_firm1.size
669
- assert_equal 1, grouped_clients_of_firm1.size
670
- end
671
-
672
- def test_adding
673
- force_signal37_to_load_all_clients_of_firm
674
- natural = Client.new("name" => "Natural Company")
675
- companies(:first_firm).clients_of_firm << natural
676
- assert_equal 2, companies(:first_firm).clients_of_firm.size # checking via the collection
677
- assert_equal 2, companies(:first_firm).clients_of_firm(true).size # checking using the db
678
- assert_equal natural, companies(:first_firm).clients_of_firm.last
679
- end
680
-
681
- def test_adding_using_create
682
- first_firm = companies(:first_firm)
683
- assert_equal 2, first_firm.plain_clients.size
684
- natural = first_firm.plain_clients.create(:name => "Natural Company")
685
- assert_equal 3, first_firm.plain_clients.length
686
- assert_equal 3, first_firm.plain_clients.size
687
- end
688
-
689
- def test_create_with_bang_on_has_many_when_parent_is_new_raises
690
- assert_raises(ActiveRecord::RecordNotSaved) do
691
- firm = Firm.new
692
- firm.plain_clients.create! :name=>"Whoever"
693
- end
694
- end
695
-
696
- def test_regular_create_on_has_many_when_parent_is_new_raises
697
- assert_raises(ActiveRecord::RecordNotSaved) do
698
- firm = Firm.new
699
- firm.plain_clients.create :name=>"Whoever"
700
- end
701
- end
702
-
703
- def test_create_with_bang_on_has_many_raises_when_record_not_saved
704
- assert_raises(ActiveRecord::RecordInvalid) do
705
- firm = Firm.find(:first)
706
- firm.plain_clients.create!
707
- end
708
- end
709
-
710
- def test_create_with_bang_on_habtm_when_parent_is_new_raises
711
- assert_raises(ActiveRecord::RecordNotSaved) do
712
- Developer.new("name" => "Aredridel").projects.create!
713
- end
714
- end
715
-
716
- def test_adding_a_mismatch_class
717
- assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << nil }
718
- assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << 1 }
719
- assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << Topic.find(1) }
720
- end
721
-
722
- def test_adding_a_collection
723
- force_signal37_to_load_all_clients_of_firm
724
- companies(:first_firm).clients_of_firm.concat([Client.new("name" => "Natural Company"), Client.new("name" => "Apple")])
725
- assert_equal 3, companies(:first_firm).clients_of_firm.size
726
- assert_equal 3, companies(:first_firm).clients_of_firm(true).size
727
- end
728
-
729
- def test_adding_before_save
730
- no_of_firms = Firm.count
731
- no_of_clients = Client.count
732
-
733
- new_firm = Firm.new("name" => "A New Firm, Inc")
734
- c = Client.new("name" => "Apple")
735
-
736
- new_firm.clients_of_firm.push Client.new("name" => "Natural Company")
737
- assert_equal 1, new_firm.clients_of_firm.size
738
- new_firm.clients_of_firm << c
739
- assert_equal 2, new_firm.clients_of_firm.size
740
-
741
- assert_equal no_of_firms, Firm.count # Firm was not saved to database.
742
- assert_equal no_of_clients, Client.count # Clients were not saved to database.
743
- assert new_firm.save
744
- assert !new_firm.new_record?
745
- assert !c.new_record?
746
- assert_equal new_firm, c.firm
747
- assert_equal no_of_firms+1, Firm.count # Firm was saved to database.
748
- assert_equal no_of_clients+2, Client.count # Clients were saved to database.
749
-
750
- assert_equal 2, new_firm.clients_of_firm.size
751
- assert_equal 2, new_firm.clients_of_firm(true).size
752
- end
753
-
754
- def test_invalid_adding
755
- firm = Firm.find(1)
756
- assert !(firm.clients_of_firm << c = Client.new)
757
- assert c.new_record?
758
- assert !firm.valid?
759
- assert !firm.save
760
- assert c.new_record?
761
- end
762
-
763
- def test_invalid_adding_before_save
764
- no_of_firms = Firm.count
765
- no_of_clients = Client.count
766
- new_firm = Firm.new("name" => "A New Firm, Inc")
767
- new_firm.clients_of_firm.concat([c = Client.new, Client.new("name" => "Apple")])
768
- assert c.new_record?
769
- assert !c.valid?
770
- assert !new_firm.valid?
771
- assert !new_firm.save
772
- assert c.new_record?
773
- assert new_firm.new_record?
774
- end
775
-
776
- def test_build
777
- new_client = companies(:first_firm).clients_of_firm.build("name" => "Another Client")
778
- assert_equal "Another Client", new_client.name
779
- assert new_client.new_record?
780
- assert_equal new_client, companies(:first_firm).clients_of_firm.last
781
- assert companies(:first_firm).save
782
- assert !new_client.new_record?
783
- assert_equal 2, companies(:first_firm).clients_of_firm(true).size
784
- end
785
-
786
- def test_build_many
787
- new_clients = companies(:first_firm).clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}])
788
- assert_equal 2, new_clients.size
789
-
790
- assert companies(:first_firm).save
791
- assert_equal 3, companies(:first_firm).clients_of_firm(true).size
792
- end
793
-
794
- def test_build_followed_by_save_does_not_load_target
795
- new_client = companies(:first_firm).clients_of_firm.build("name" => "Another Client")
796
- assert companies(:first_firm).save
797
- assert !companies(:first_firm).clients_of_firm.loaded?
798
- end
799
-
800
- def test_build_without_loading_association
801
- first_topic = topics(:first)
802
- Reply.column_names
803
-
804
- assert_equal 1, first_topic.replies.length
805
-
806
- assert_no_queries do
807
- first_topic.replies.build(:title => "Not saved", :content => "Superstars")
808
- assert_equal 2, first_topic.replies.size
809
- end
810
-
811
- assert_equal 2, first_topic.replies.to_ary.size
812
- end
813
-
814
- def test_create_without_loading_association
815
- first_firm = companies(:first_firm)
816
- Firm.column_names
817
- Client.column_names
818
-
819
- assert_equal 1, first_firm.clients_of_firm.size
820
- first_firm.clients_of_firm.reset
821
-
822
- assert_queries(1) do
823
- first_firm.clients_of_firm.create(:name => "Superstars")
824
- end
825
-
826
- assert_equal 2, first_firm.clients_of_firm.size
827
- end
828
-
829
- def test_invalid_build
830
- new_client = companies(:first_firm).clients_of_firm.build
831
- assert new_client.new_record?
832
- assert !new_client.valid?
833
- assert_equal new_client, companies(:first_firm).clients_of_firm.last
834
- assert !companies(:first_firm).save
835
- assert new_client.new_record?
836
- assert_equal 1, companies(:first_firm).clients_of_firm(true).size
837
- end
838
-
839
- def test_create
840
- force_signal37_to_load_all_clients_of_firm
841
- new_client = companies(:first_firm).clients_of_firm.create("name" => "Another Client")
842
- assert !new_client.new_record?
843
- assert_equal new_client, companies(:first_firm).clients_of_firm.last
844
- assert_equal new_client, companies(:first_firm).clients_of_firm(true).last
845
- end
846
-
847
- def test_create_many
848
- companies(:first_firm).clients_of_firm.create([{"name" => "Another Client"}, {"name" => "Another Client II"}])
849
- assert_equal 3, companies(:first_firm).clients_of_firm(true).size
850
- end
851
-
852
- def test_create_followed_by_save_does_not_load_target
853
- new_client = companies(:first_firm).clients_of_firm.create("name" => "Another Client")
854
- assert companies(:first_firm).save
855
- assert !companies(:first_firm).clients_of_firm.loaded?
856
- end
857
-
858
- def test_find_or_initialize
859
- the_client = companies(:first_firm).clients.find_or_initialize_by_name("Yet another client")
860
- assert_equal companies(:first_firm).id, the_client.firm_id
861
- assert_equal "Yet another client", the_client.name
862
- assert the_client.new_record?
863
- end
864
-
865
- def test_find_or_create
866
- number_of_clients = companies(:first_firm).clients.size
867
- the_client = companies(:first_firm).clients.find_or_create_by_name("Yet another client")
868
- assert_equal number_of_clients + 1, companies(:first_firm, :reload).clients.size
869
- assert_equal the_client, companies(:first_firm).clients.find_or_create_by_name("Yet another client")
870
- assert_equal number_of_clients + 1, companies(:first_firm, :reload).clients.size
871
- end
872
-
873
- def test_deleting
874
- force_signal37_to_load_all_clients_of_firm
875
- companies(:first_firm).clients_of_firm.delete(companies(:first_firm).clients_of_firm.first)
876
- assert_equal 0, companies(:first_firm).clients_of_firm.size
877
- assert_equal 0, companies(:first_firm).clients_of_firm(true).size
878
- end
879
-
880
- def test_deleting_before_save
881
- new_firm = Firm.new("name" => "A New Firm, Inc.")
882
- new_client = new_firm.clients_of_firm.build("name" => "Another Client")
883
- assert_equal 1, new_firm.clients_of_firm.size
884
- new_firm.clients_of_firm.delete(new_client)
885
- assert_equal 0, new_firm.clients_of_firm.size
886
- end
887
-
888
- def test_deleting_a_collection
889
- force_signal37_to_load_all_clients_of_firm
890
- companies(:first_firm).clients_of_firm.create("name" => "Another Client")
891
- assert_equal 2, companies(:first_firm).clients_of_firm.size
892
- companies(:first_firm).clients_of_firm.delete([companies(:first_firm).clients_of_firm[0], companies(:first_firm).clients_of_firm[1]])
893
- assert_equal 0, companies(:first_firm).clients_of_firm.size
894
- assert_equal 0, companies(:first_firm).clients_of_firm(true).size
895
- end
896
-
897
- def test_delete_all
898
- force_signal37_to_load_all_clients_of_firm
899
- companies(:first_firm).clients_of_firm.create("name" => "Another Client")
900
- assert_equal 2, companies(:first_firm).clients_of_firm.size
901
- companies(:first_firm).clients_of_firm.delete_all
902
- assert_equal 0, companies(:first_firm).clients_of_firm.size
903
- assert_equal 0, companies(:first_firm).clients_of_firm(true).size
904
- end
905
-
906
- def test_delete_all_with_not_yet_loaded_association_collection
907
- force_signal37_to_load_all_clients_of_firm
908
- companies(:first_firm).clients_of_firm.create("name" => "Another Client")
909
- assert_equal 2, companies(:first_firm).clients_of_firm.size
910
- companies(:first_firm).clients_of_firm.reset
911
- companies(:first_firm).clients_of_firm.delete_all
912
- assert_equal 0, companies(:first_firm).clients_of_firm.size
913
- assert_equal 0, companies(:first_firm).clients_of_firm(true).size
914
- end
915
-
916
- def test_clearing_an_association_collection
917
- firm = companies(:first_firm)
918
- client_id = firm.clients_of_firm.first.id
919
- assert_equal 1, firm.clients_of_firm.size
920
-
921
- firm.clients_of_firm.clear
922
-
923
- assert_equal 0, firm.clients_of_firm.size
924
- assert_equal 0, firm.clients_of_firm(true).size
925
- assert_equal [], Client.destroyed_client_ids[firm.id]
926
-
927
- # Should not be destroyed since the association is not dependent.
928
- assert_nothing_raised do
929
- assert Client.find(client_id).firm.nil?
930
- end
931
- end
932
-
933
- def test_clearing_a_dependent_association_collection
934
- firm = companies(:first_firm)
935
- client_id = firm.dependent_clients_of_firm.first.id
936
- assert_equal 1, firm.dependent_clients_of_firm.size
937
-
938
- # :dependent means destroy is called on each client
939
- firm.dependent_clients_of_firm.clear
940
-
941
- assert_equal 0, firm.dependent_clients_of_firm.size
942
- assert_equal 0, firm.dependent_clients_of_firm(true).size
943
- assert_equal [client_id], Client.destroyed_client_ids[firm.id]
944
-
945
- # Should be destroyed since the association is dependent.
946
- assert Client.find_by_id(client_id).nil?
947
- end
948
-
949
- def test_clearing_an_exclusively_dependent_association_collection
950
- firm = companies(:first_firm)
951
- client_id = firm.exclusively_dependent_clients_of_firm.first.id
952
- assert_equal 1, firm.exclusively_dependent_clients_of_firm.size
953
-
954
- assert_equal [], Client.destroyed_client_ids[firm.id]
955
-
956
- # :exclusively_dependent means each client is deleted directly from
957
- # the database without looping through them calling destroy.
958
- firm.exclusively_dependent_clients_of_firm.clear
959
-
960
- assert_equal 0, firm.exclusively_dependent_clients_of_firm.size
961
- assert_equal 0, firm.exclusively_dependent_clients_of_firm(true).size
962
- # no destroy-filters should have been called
963
- assert_equal [], Client.destroyed_client_ids[firm.id]
964
-
965
- # Should be destroyed since the association is exclusively dependent.
966
- assert Client.find_by_id(client_id).nil?
967
- end
968
-
969
- def test_dependent_association_respects_optional_conditions_on_delete
970
- firm = companies(:odegy)
971
- Client.create(:client_of => firm.id, :name => "BigShot Inc.")
972
- Client.create(:client_of => firm.id, :name => "SmallTime Inc.")
973
- # only one of two clients is included in the association due to the :conditions key
974
- assert_equal 2, Client.find_all_by_client_of(firm.id).size
975
- assert_equal 1, firm.dependent_conditional_clients_of_firm.size
976
- firm.destroy
977
- # only the correctly associated client should have been deleted
978
- assert_equal 1, Client.find_all_by_client_of(firm.id).size
979
- end
980
-
981
- def test_dependent_association_respects_optional_sanitized_conditions_on_delete
982
- firm = companies(:odegy)
983
- Client.create(:client_of => firm.id, :name => "BigShot Inc.")
984
- Client.create(:client_of => firm.id, :name => "SmallTime Inc.")
985
- # only one of two clients is included in the association due to the :conditions key
986
- assert_equal 2, Client.find_all_by_client_of(firm.id).size
987
- assert_equal 1, firm.dependent_sanitized_conditional_clients_of_firm.size
988
- firm.destroy
989
- # only the correctly associated client should have been deleted
990
- assert_equal 1, Client.find_all_by_client_of(firm.id).size
991
- end
992
-
993
- def test_clearing_without_initial_access
994
- firm = companies(:first_firm)
995
-
996
- firm.clients_of_firm.clear
997
-
998
- assert_equal 0, firm.clients_of_firm.size
999
- assert_equal 0, firm.clients_of_firm(true).size
1000
- end
1001
-
1002
- def test_deleting_a_item_which_is_not_in_the_collection
1003
- force_signal37_to_load_all_clients_of_firm
1004
- summit = Client.find_by_name('Summit')
1005
- companies(:first_firm).clients_of_firm.delete(summit)
1006
- assert_equal 1, companies(:first_firm).clients_of_firm.size
1007
- assert_equal 1, companies(:first_firm).clients_of_firm(true).size
1008
- assert_equal 2, summit.client_of
1009
- end
1010
-
1011
- def test_deleting_type_mismatch
1012
- david = Developer.find(1)
1013
- david.projects.reload
1014
- assert_raises(ActiveRecord::AssociationTypeMismatch) { david.projects.delete(1) }
1015
- end
1016
-
1017
- def test_deleting_self_type_mismatch
1018
- david = Developer.find(1)
1019
- david.projects.reload
1020
- assert_raises(ActiveRecord::AssociationTypeMismatch) { david.projects.delete(Project.find(1).developers) }
1021
- end
1022
-
1023
- def test_destroy_all
1024
- force_signal37_to_load_all_clients_of_firm
1025
- assert !companies(:first_firm).clients_of_firm.empty?, "37signals has clients after load"
1026
- companies(:first_firm).clients_of_firm.destroy_all
1027
- assert companies(:first_firm).clients_of_firm.empty?, "37signals has no clients after destroy all"
1028
- assert companies(:first_firm).clients_of_firm(true).empty?, "37signals has no clients after destroy all and refresh"
1029
- end
1030
-
1031
- def test_dependence
1032
- firm = companies(:first_firm)
1033
- assert_equal 2, firm.clients.size
1034
- firm.destroy
1035
- assert Client.find(:all, :conditions => "firm_id=#{firm.id}").empty?
1036
- end
1037
-
1038
- def test_destroy_dependent_when_deleted_from_association
1039
- firm = Firm.find(:first)
1040
- assert_equal 2, firm.clients.size
1041
-
1042
- client = firm.clients.first
1043
- firm.clients.delete(client)
1044
-
1045
- assert_raise(ActiveRecord::RecordNotFound) { Client.find(client.id) }
1046
- assert_raise(ActiveRecord::RecordNotFound) { firm.clients.find(client.id) }
1047
- assert_equal 1, firm.clients.size
1048
- end
1049
-
1050
- def test_three_levels_of_dependence
1051
- topic = Topic.create "title" => "neat and simple"
1052
- reply = topic.replies.create "title" => "neat and simple", "content" => "still digging it"
1053
- silly_reply = reply.replies.create "title" => "neat and simple", "content" => "ain't complaining"
1054
-
1055
- assert_nothing_raised { topic.destroy }
1056
- end
1057
-
1058
- uses_transaction :test_dependence_with_transaction_support_on_failure
1059
- def test_dependence_with_transaction_support_on_failure
1060
- firm = companies(:first_firm)
1061
- clients = firm.clients
1062
- assert_equal 2, clients.length
1063
- clients.last.instance_eval { def before_destroy() raise "Trigger rollback" end }
1064
-
1065
- firm.destroy rescue "do nothing"
1066
-
1067
- assert_equal 2, Client.find(:all, :conditions => "firm_id=#{firm.id}").size
1068
- end
1069
-
1070
- def test_dependence_on_account
1071
- num_accounts = Account.count
1072
- companies(:first_firm).destroy
1073
- assert_equal num_accounts - 1, Account.count
1074
- end
1075
-
1076
- def test_depends_and_nullify
1077
- num_accounts = Account.count
1078
- num_companies = Company.count
1079
-
1080
- core = companies(:rails_core)
1081
- assert_equal accounts(:rails_core_account), core.account
1082
- assert_equal companies(:leetsoft, :jadedpixel), core.companies
1083
- core.destroy
1084
- assert_nil accounts(:rails_core_account).reload.firm_id
1085
- assert_nil companies(:leetsoft).reload.client_of
1086
- assert_nil companies(:jadedpixel).reload.client_of
1087
-
1088
-
1089
- assert_equal num_accounts, Account.count
1090
- end
1091
-
1092
- def test_included_in_collection
1093
- assert companies(:first_firm).clients.include?(Client.find(2))
1094
- end
1095
-
1096
- def test_adding_array_and_collection
1097
- assert_nothing_raised { Firm.find(:first).clients + Firm.find(:all).last.clients }
1098
- end
1099
-
1100
- def test_find_all_without_conditions
1101
- firm = companies(:first_firm)
1102
- assert_equal 2, firm.clients.find(:all).length
1103
- end
1104
-
1105
- def test_replace_with_less
1106
- firm = Firm.find(:first)
1107
- firm.clients = [companies(:first_client)]
1108
- assert firm.save, "Could not save firm"
1109
- firm.reload
1110
- assert_equal 1, firm.clients.length
1111
- end
1112
-
1113
- def test_replace_with_less_and_dependent_nullify
1114
- num_companies = Company.count
1115
- companies(:rails_core).companies = []
1116
- assert_equal num_companies, Company.count
1117
- end
1118
-
1119
- def test_replace_with_new
1120
- firm = Firm.find(:first)
1121
- firm.clients = [companies(:second_client), Client.new("name" => "New Client")]
1122
- firm.save
1123
- firm.reload
1124
- assert_equal 2, firm.clients.length
1125
- assert !firm.clients.include?(:first_client)
1126
- end
1127
-
1128
- def test_replace_on_new_object
1129
- firm = Firm.new("name" => "New Firm")
1130
- firm.clients = [companies(:second_client), Client.new("name" => "New Client")]
1131
- assert firm.save
1132
- firm.reload
1133
- assert_equal 2, firm.clients.length
1134
- assert firm.clients.include?(Client.find_by_name("New Client"))
1135
- end
1136
-
1137
- def test_get_ids
1138
- assert_equal [companies(:first_client).id, companies(:second_client).id], companies(:first_firm).client_ids
1139
- end
1140
-
1141
- def test_assign_ids
1142
- firm = Firm.new("name" => "Apple")
1143
- firm.client_ids = [companies(:first_client).id, companies(:second_client).id]
1144
- firm.save
1145
- firm.reload
1146
- assert_equal 2, firm.clients.length
1147
- assert firm.clients.include?(companies(:second_client))
1148
- end
1149
-
1150
- def test_assign_ids_ignoring_blanks
1151
- firm = Firm.create!(:name => 'Apple')
1152
- firm.client_ids = [companies(:first_client).id, nil, companies(:second_client).id, '']
1153
- firm.save!
1154
-
1155
- assert_equal 2, firm.clients(true).size
1156
- assert firm.clients.include?(companies(:second_client))
1157
- end
1158
-
1159
- def test_get_ids_for_through
1160
- assert_equal [comments(:eager_other_comment1).id], authors(:mary).comment_ids
1161
- end
1162
-
1163
- def test_assign_ids_for_through
1164
- assert_raise(NoMethodError) { authors(:mary).comment_ids = [123] }
1165
- end
1166
-
1167
- def test_dynamic_find_should_respect_association_order_for_through
1168
- assert_equal Comment.find(10), authors(:david).comments_desc.find(:first, :conditions => "comments.type = 'SpecialComment'")
1169
- assert_equal Comment.find(10), authors(:david).comments_desc.find_by_type('SpecialComment')
1170
- end
1171
-
1172
- def test_dynamic_find_order_should_override_association_order_for_through
1173
- assert_equal Comment.find(3), authors(:david).comments_desc.find(:first, :conditions => "comments.type = 'SpecialComment'", :order => 'comments.id')
1174
- assert_equal Comment.find(3), authors(:david).comments_desc.find_by_type('SpecialComment', :order => 'comments.id')
1175
- end
1176
-
1177
- def test_dynamic_find_all_should_respect_association_order_for_through
1178
- assert_equal [Comment.find(10), Comment.find(7), Comment.find(6), Comment.find(3)], authors(:david).comments_desc.find(:all, :conditions => "comments.type = 'SpecialComment'")
1179
- assert_equal [Comment.find(10), Comment.find(7), Comment.find(6), Comment.find(3)], authors(:david).comments_desc.find_all_by_type('SpecialComment')
1180
- end
1181
-
1182
- def test_dynamic_find_all_order_should_override_association_order_for_through
1183
- assert_equal [Comment.find(3), Comment.find(6), Comment.find(7), Comment.find(10)], authors(:david).comments_desc.find(:all, :conditions => "comments.type = 'SpecialComment'", :order => 'comments.id')
1184
- assert_equal [Comment.find(3), Comment.find(6), Comment.find(7), Comment.find(10)], authors(:david).comments_desc.find_all_by_type('SpecialComment', :order => 'comments.id')
1185
- end
1186
-
1187
- def test_dynamic_find_all_should_respect_association_limit_for_through
1188
- assert_equal 1, authors(:david).limited_comments.find(:all, :conditions => "comments.type = 'SpecialComment'").length
1189
- assert_equal 1, authors(:david).limited_comments.find_all_by_type('SpecialComment').length
1190
- end
1191
-
1192
- def test_dynamic_find_all_order_should_override_association_limit_for_through
1193
- assert_equal 4, authors(:david).limited_comments.find(:all, :conditions => "comments.type = 'SpecialComment'", :limit => 9_000).length
1194
- assert_equal 4, authors(:david).limited_comments.find_all_by_type('SpecialComment', :limit => 9_000).length
1195
- end
1196
-
1197
- end
1198
-
1199
- class BelongsToAssociationsTest < Test::Unit::TestCase
1200
- fixtures :accounts, :companies, :developers, :projects, :topics,
1201
- :developers_projects, :computers, :authors, :posts, :tags, :taggings
1202
-
1203
- def test_belongs_to
1204
- Client.find(3).firm.name
1205
- assert_equal companies(:first_firm).name, Client.find(3).firm.name
1206
- assert !Client.find(3).firm.nil?, "Microsoft should have a firm"
1207
- end
1208
-
1209
- def test_proxy_assignment
1210
- account = Account.find(1)
1211
- assert_nothing_raised { account.firm = account.firm }
1212
- end
1213
-
1214
- def test_triple_equality
1215
- assert Client.find(3).firm === Firm
1216
- assert Firm === Client.find(3).firm
1217
- end
1218
-
1219
- def test_type_mismatch
1220
- assert_raise(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = 1 }
1221
- assert_raise(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = Project.find(1) }
1222
- end
1223
-
1224
- def test_natural_assignment
1225
- apple = Firm.create("name" => "Apple")
1226
- citibank = Account.create("credit_limit" => 10)
1227
- citibank.firm = apple
1228
- assert_equal apple.id, citibank.firm_id
1229
- end
1230
-
1231
- def test_no_unexpected_aliasing
1232
- first_firm = companies(:first_firm)
1233
- another_firm = companies(:another_firm)
1234
-
1235
- citibank = Account.create("credit_limit" => 10)
1236
- citibank.firm = first_firm
1237
- original_proxy = citibank.firm
1238
- citibank.firm = another_firm
1239
-
1240
- assert_equal first_firm.object_id, original_proxy.object_id
1241
- assert_equal another_firm.object_id, citibank.firm.object_id
1242
- end
1243
-
1244
- def test_creating_the_belonging_object
1245
- citibank = Account.create("credit_limit" => 10)
1246
- apple = citibank.create_firm("name" => "Apple")
1247
- assert_equal apple, citibank.firm
1248
- citibank.save
1249
- citibank.reload
1250
- assert_equal apple, citibank.firm
1251
- end
1252
-
1253
- def test_building_the_belonging_object
1254
- citibank = Account.create("credit_limit" => 10)
1255
- apple = citibank.build_firm("name" => "Apple")
1256
- citibank.save
1257
- assert_equal apple.id, citibank.firm_id
1258
- end
1259
-
1260
- def test_natural_assignment_to_nil
1261
- client = Client.find(3)
1262
- client.firm = nil
1263
- client.save
1264
- assert_nil client.firm(true)
1265
- assert_nil client.client_of
1266
- end
1267
-
1268
- def test_with_different_class_name
1269
- assert_equal Company.find(1).name, Company.find(3).firm_with_other_name.name
1270
- assert_not_nil Company.find(3).firm_with_other_name, "Microsoft should have a firm"
1271
- end
1272
-
1273
- def test_with_condition
1274
- assert_equal Company.find(1).name, Company.find(3).firm_with_condition.name
1275
- assert_not_nil Company.find(3).firm_with_condition, "Microsoft should have a firm"
1276
- end
1277
-
1278
- def test_belongs_to_counter
1279
- debate = Topic.create("title" => "debate")
1280
- assert_equal 0, debate.send(:read_attribute, "replies_count"), "No replies yet"
1281
-
1282
- trash = debate.replies.create("title" => "blah!", "content" => "world around!")
1283
- assert_equal 1, Topic.find(debate.id).send(:read_attribute, "replies_count"), "First reply created"
1284
-
1285
- trash.destroy
1286
- assert_equal 0, Topic.find(debate.id).send(:read_attribute, "replies_count"), "First reply deleted"
1287
- end
1288
-
1289
- def test_belongs_to_counter_with_reassigning
1290
- t1 = Topic.create("title" => "t1")
1291
- t2 = Topic.create("title" => "t2")
1292
- r1 = Reply.new("title" => "r1", "content" => "r1")
1293
- r1.topic = t1
1294
-
1295
- assert r1.save
1296
- assert_equal 1, Topic.find(t1.id).replies.size
1297
- assert_equal 0, Topic.find(t2.id).replies.size
1298
-
1299
- r1.topic = Topic.find(t2.id)
1300
-
1301
- assert r1.save
1302
- assert_equal 0, Topic.find(t1.id).replies.size
1303
- assert_equal 1, Topic.find(t2.id).replies.size
1304
-
1305
- r1.topic = nil
1306
-
1307
- assert_equal 0, Topic.find(t1.id).replies.size
1308
- assert_equal 0, Topic.find(t2.id).replies.size
1309
-
1310
- r1.topic = t1
1311
-
1312
- assert_equal 1, Topic.find(t1.id).replies.size
1313
- assert_equal 0, Topic.find(t2.id).replies.size
1314
-
1315
- r1.destroy
1316
-
1317
- assert_equal 0, Topic.find(t1.id).replies.size
1318
- assert_equal 0, Topic.find(t2.id).replies.size
1319
- end
1320
-
1321
- def test_belongs_to_counter_after_save
1322
- topic = Topic.create!(:title => "monday night")
1323
- topic.replies.create!(:title => "re: monday night", :content => "football")
1324
- assert_equal 1, Topic.find(topic.id)[:replies_count]
1325
-
1326
- topic.save!
1327
- assert_equal 1, Topic.find(topic.id)[:replies_count]
1328
- end
1329
-
1330
- def test_belongs_to_counter_after_update_attributes
1331
- topic = Topic.create!(:title => "37s")
1332
- topic.replies.create!(:title => "re: 37s", :content => "rails")
1333
- assert_equal 1, Topic.find(topic.id)[:replies_count]
1334
-
1335
- topic.update_attributes(:title => "37signals")
1336
- assert_equal 1, Topic.find(topic.id)[:replies_count]
1337
- end
1338
-
1339
- def test_belongs_to_counter_after_save
1340
- topic = Topic.create("title" => "monday night")
1341
- topic.replies.create("title" => "re: monday night", "content" => "football")
1342
- assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count")
1343
-
1344
- topic.save
1345
- assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count")
1346
- end
1347
-
1348
- def test_belongs_to_counter_after_update_attributes
1349
- topic = Topic.create("title" => "37s")
1350
- topic.replies.create("title" => "re: 37s", "content" => "rails")
1351
- assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count")
1352
-
1353
- topic.update_attributes("title" => "37signals")
1354
- assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count")
1355
- end
1356
-
1357
- def test_assignment_before_parent_saved
1358
- client = Client.find(:first)
1359
- apple = Firm.new("name" => "Apple")
1360
- client.firm = apple
1361
- assert_equal apple, client.firm
1362
- assert apple.new_record?
1363
- assert client.save
1364
- assert apple.save
1365
- assert !apple.new_record?
1366
- assert_equal apple, client.firm
1367
- assert_equal apple, client.firm(true)
1368
- end
1369
-
1370
- def test_assignment_before_child_saved
1371
- final_cut = Client.new("name" => "Final Cut")
1372
- firm = Firm.find(1)
1373
- final_cut.firm = firm
1374
- assert final_cut.new_record?
1375
- assert final_cut.save
1376
- assert !final_cut.new_record?
1377
- assert !firm.new_record?
1378
- assert_equal firm, final_cut.firm
1379
- assert_equal firm, final_cut.firm(true)
1380
- end
1381
-
1382
- def test_assignment_before_either_saved
1383
- final_cut = Client.new("name" => "Final Cut")
1384
- apple = Firm.new("name" => "Apple")
1385
- final_cut.firm = apple
1386
- assert final_cut.new_record?
1387
- assert apple.new_record?
1388
- assert final_cut.save
1389
- assert !final_cut.new_record?
1390
- assert !apple.new_record?
1391
- assert_equal apple, final_cut.firm
1392
- assert_equal apple, final_cut.firm(true)
1393
- end
1394
-
1395
- def test_new_record_with_foreign_key_but_no_object
1396
- c = Client.new("firm_id" => 1)
1397
- assert_equal Firm.find(:first), c.firm_with_basic_id
1398
- end
1399
-
1400
- def test_forgetting_the_load_when_foreign_key_enters_late
1401
- c = Client.new
1402
- assert_nil c.firm_with_basic_id
1403
-
1404
- c.firm_id = 1
1405
- assert_equal Firm.find(:first), c.firm_with_basic_id
1406
- end
1407
-
1408
- def test_field_name_same_as_foreign_key
1409
- computer = Computer.find(1)
1410
- assert_not_nil computer.developer, ":foreign key == attribute didn't lock up" # '
1411
- end
1412
-
1413
- def test_counter_cache
1414
- topic = Topic.create :title => "Zoom-zoom-zoom"
1415
- assert_equal 0, topic[:replies_count]
1416
-
1417
- reply = Reply.create(:title => "re: zoom", :content => "speedy quick!")
1418
- reply.topic = topic
1419
-
1420
- assert_equal 1, topic.reload[:replies_count]
1421
- assert_equal 1, topic.replies.size
1422
-
1423
- topic[:replies_count] = 15
1424
- assert_equal 15, topic.replies.size
1425
- end
1426
-
1427
- def test_custom_counter_cache
1428
- reply = Reply.create(:title => "re: zoom", :content => "speedy quick!")
1429
- assert_equal 0, reply[:replies_count]
1430
-
1431
- silly = SillyReply.create(:title => "gaga", :content => "boo-boo")
1432
- silly.reply = reply
1433
-
1434
- assert_equal 1, reply.reload[:replies_count]
1435
- assert_equal 1, reply.replies.size
1436
-
1437
- reply[:replies_count] = 17
1438
- assert_equal 17, reply.replies.size
1439
- end
1440
-
1441
- def test_store_two_association_with_one_save
1442
- num_orders = Order.count
1443
- num_customers = Customer.count
1444
- order = Order.new
1445
-
1446
- customer1 = order.billing = Customer.new
1447
- customer2 = order.shipping = Customer.new
1448
- assert order.save
1449
- assert_equal customer1, order.billing
1450
- assert_equal customer2, order.shipping
1451
-
1452
- order.reload
1453
-
1454
- assert_equal customer1, order.billing
1455
- assert_equal customer2, order.shipping
1456
-
1457
- assert_equal num_orders +1, Order.count
1458
- assert_equal num_customers +2, Customer.count
1459
- end
1460
-
1461
-
1462
- def test_store_association_in_two_relations_with_one_save
1463
- num_orders = Order.count
1464
- num_customers = Customer.count
1465
- order = Order.new
1466
-
1467
- customer = order.billing = order.shipping = Customer.new
1468
- assert order.save
1469
- assert_equal customer, order.billing
1470
- assert_equal customer, order.shipping
1471
-
1472
- order.reload
1473
-
1474
- assert_equal customer, order.billing
1475
- assert_equal customer, order.shipping
1476
-
1477
- assert_equal num_orders +1, Order.count
1478
- assert_equal num_customers +1, Customer.count
1479
- end
1480
-
1481
- def test_store_association_in_two_relations_with_one_save_in_existing_object
1482
- num_orders = Order.count
1483
- num_customers = Customer.count
1484
- order = Order.create
1485
-
1486
- customer = order.billing = order.shipping = Customer.new
1487
- assert order.save
1488
- assert_equal customer, order.billing
1489
- assert_equal customer, order.shipping
1490
-
1491
- order.reload
1492
-
1493
- assert_equal customer, order.billing
1494
- assert_equal customer, order.shipping
1495
-
1496
- assert_equal num_orders +1, Order.count
1497
- assert_equal num_customers +1, Customer.count
1498
- end
1499
-
1500
- def test_store_association_in_two_relations_with_one_save_in_existing_object_with_values
1501
- num_orders = Order.count
1502
- num_customers = Customer.count
1503
- order = Order.create
1504
-
1505
- customer = order.billing = order.shipping = Customer.new
1506
- assert order.save
1507
- assert_equal customer, order.billing
1508
- assert_equal customer, order.shipping
1509
-
1510
- order.reload
1511
-
1512
- customer = order.billing = order.shipping = Customer.new
1513
-
1514
- assert order.save
1515
- order.reload
1516
-
1517
- assert_equal customer, order.billing
1518
- assert_equal customer, order.shipping
1519
-
1520
- assert_equal num_orders +1, Order.count
1521
- assert_equal num_customers +2, Customer.count
1522
- end
1523
-
1524
-
1525
- def test_association_assignment_sticks
1526
- post = Post.find(:first)
1527
-
1528
- author1, author2 = Author.find(:all, :limit => 2)
1529
- assert_not_nil author1
1530
- assert_not_nil author2
1531
-
1532
- # make sure the association is loaded
1533
- post.author
1534
-
1535
- # set the association by id, directly
1536
- post.author_id = author2.id
1537
-
1538
- # save and reload
1539
- post.save!
1540
- post.reload
1541
-
1542
- # the author id of the post should be the id we set
1543
- assert_equal post.author_id, author2.id
1544
- end
1545
-
1546
- end
1547
-
1548
-
1549
- class ProjectWithAfterCreateHook < ActiveRecord::Base
1550
- set_table_name 'projects'
1551
- has_and_belongs_to_many :developers,
1552
- :class_name => "DeveloperForProjectWithAfterCreateHook",
1553
- :join_table => "developers_projects",
1554
- :foreign_key => "project_id",
1555
- :association_foreign_key => "developer_id"
1556
-
1557
- after_create :add_david
1558
-
1559
- def add_david
1560
- david = DeveloperForProjectWithAfterCreateHook.find_by_name('David')
1561
- david.projects << self
1562
- end
1563
- end
1564
-
1565
- class DeveloperForProjectWithAfterCreateHook < ActiveRecord::Base
1566
- set_table_name 'developers'
1567
- has_and_belongs_to_many :projects,
1568
- :class_name => "ProjectWithAfterCreateHook",
1569
- :join_table => "developers_projects",
1570
- :association_foreign_key => "project_id",
1571
- :foreign_key => "developer_id"
1572
- end
1573
-
1574
-
1575
- class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1576
- fixtures :accounts, :companies, :categories, :posts, :categories_posts, :developers, :projects, :developers_projects
1577
-
1578
- def test_has_and_belongs_to_many
1579
- david = Developer.find(1)
1580
-
1581
- assert !david.projects.empty?
1582
- assert_equal 2, david.projects.size
1583
-
1584
- active_record = Project.find(1)
1585
- assert !active_record.developers.empty?
1586
- assert_equal 3, active_record.developers.size
1587
- assert active_record.developers.include?(david)
1588
- end
1589
-
1590
- def test_triple_equality
1591
- assert !(Array === Developer.find(1).projects)
1592
- assert Developer.find(1).projects === Array
1593
- end
1594
-
1595
- def test_adding_single
1596
- jamis = Developer.find(2)
1597
- jamis.projects.reload # causing the collection to load
1598
- action_controller = Project.find(2)
1599
- assert_equal 1, jamis.projects.size
1600
- assert_equal 1, action_controller.developers.size
1601
-
1602
- jamis.projects << action_controller
1603
-
1604
- assert_equal 2, jamis.projects.size
1605
- assert_equal 2, jamis.projects(true).size
1606
- assert_equal 2, action_controller.developers(true).size
1607
- end
1608
-
1609
- def test_adding_type_mismatch
1610
- jamis = Developer.find(2)
1611
- assert_raise(ActiveRecord::AssociationTypeMismatch) { jamis.projects << nil }
1612
- assert_raise(ActiveRecord::AssociationTypeMismatch) { jamis.projects << 1 }
1613
- end
1614
-
1615
- def test_adding_from_the_project
1616
- jamis = Developer.find(2)
1617
- action_controller = Project.find(2)
1618
- action_controller.developers.reload
1619
- assert_equal 1, jamis.projects.size
1620
- assert_equal 1, action_controller.developers.size
1621
-
1622
- action_controller.developers << jamis
1623
-
1624
- assert_equal 2, jamis.projects(true).size
1625
- assert_equal 2, action_controller.developers.size
1626
- assert_equal 2, action_controller.developers(true).size
1627
- end
1628
-
1629
- def test_adding_from_the_project_fixed_timestamp
1630
- jamis = Developer.find(2)
1631
- action_controller = Project.find(2)
1632
- action_controller.developers.reload
1633
- assert_equal 1, jamis.projects.size
1634
- assert_equal 1, action_controller.developers.size
1635
- updated_at = jamis.updated_at
1636
-
1637
- action_controller.developers << jamis
1638
-
1639
- assert_equal updated_at, jamis.updated_at
1640
- assert_equal 2, jamis.projects(true).size
1641
- assert_equal 2, action_controller.developers.size
1642
- assert_equal 2, action_controller.developers(true).size
1643
- end
1644
-
1645
- def test_adding_multiple
1646
- aredridel = Developer.new("name" => "Aredridel")
1647
- aredridel.save
1648
- aredridel.projects.reload
1649
- aredridel.projects.push(Project.find(1), Project.find(2))
1650
- assert_equal 2, aredridel.projects.size
1651
- assert_equal 2, aredridel.projects(true).size
1652
- end
1653
-
1654
- def test_adding_a_collection
1655
- aredridel = Developer.new("name" => "Aredridel")
1656
- aredridel.save
1657
- aredridel.projects.reload
1658
- aredridel.projects.concat([Project.find(1), Project.find(2)])
1659
- assert_equal 2, aredridel.projects.size
1660
- assert_equal 2, aredridel.projects(true).size
1661
- end
1662
-
1663
- def test_adding_uses_default_values_on_join_table
1664
- ac = projects(:action_controller)
1665
- assert !developers(:jamis).projects.include?(ac)
1666
- developers(:jamis).projects << ac
1667
-
1668
- assert developers(:jamis, :reload).projects.include?(ac)
1669
- project = developers(:jamis).projects.detect { |p| p == ac }
1670
- assert_equal 1, project.access_level.to_i
1671
- end
1672
-
1673
- def test_habtm_attribute_access_and_respond_to
1674
- project = developers(:jamis).projects[0]
1675
- assert project.has_attribute?("name")
1676
- assert project.has_attribute?("joined_on")
1677
- assert project.has_attribute?("access_level")
1678
- assert project.respond_to?("name")
1679
- assert project.respond_to?("name=")
1680
- assert project.respond_to?("name?")
1681
- assert project.respond_to?("joined_on")
1682
- # given that the 'join attribute' won't be persisted, I don't
1683
- # think we should define the mutators
1684
- #assert project.respond_to?("joined_on=")
1685
- assert project.respond_to?("joined_on?")
1686
- assert project.respond_to?("access_level")
1687
- #assert project.respond_to?("access_level=")
1688
- assert project.respond_to?("access_level?")
1689
- end
1690
-
1691
- def test_habtm_adding_before_save
1692
- no_of_devels = Developer.count
1693
- no_of_projects = Project.count
1694
- aredridel = Developer.new("name" => "Aredridel")
1695
- aredridel.projects.concat([Project.find(1), p = Project.new("name" => "Projekt")])
1696
- assert aredridel.new_record?
1697
- assert p.new_record?
1698
- assert aredridel.save
1699
- assert !aredridel.new_record?
1700
- assert_equal no_of_devels+1, Developer.count
1701
- assert_equal no_of_projects+1, Project.count
1702
- assert_equal 2, aredridel.projects.size
1703
- assert_equal 2, aredridel.projects(true).size
1704
- end
1705
-
1706
- def test_habtm_saving_multiple_relationships
1707
- new_project = Project.new("name" => "Grimetime")
1708
- amount_of_developers = 4
1709
- developers = (0...amount_of_developers).collect {|i| Developer.create(:name => "JME #{i}") }.reverse
1710
-
1711
- new_project.developer_ids = [developers[0].id, developers[1].id]
1712
- new_project.developers_with_callback_ids = [developers[2].id, developers[3].id]
1713
- assert new_project.save
1714
-
1715
- new_project.reload
1716
- assert_equal amount_of_developers, new_project.developers.size
1717
- assert_equal developers, new_project.developers
1718
- end
1719
-
1720
- def test_habtm_unique_order_preserved
1721
- assert_equal developers(:poor_jamis, :jamis, :david), projects(:active_record).non_unique_developers
1722
- assert_equal developers(:poor_jamis, :jamis, :david), projects(:active_record).developers
1723
- end
1724
-
1725
- def test_build
1726
- devel = Developer.find(1)
1727
- proj = devel.projects.build("name" => "Projekt")
1728
- assert_equal devel.projects.last, proj
1729
- assert proj.new_record?
1730
- devel.save
1731
- assert !proj.new_record?
1732
- assert_equal devel.projects.last, proj
1733
- assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated
1734
- end
1735
-
1736
- def test_build_by_new_record
1737
- devel = Developer.new(:name => "Marcel", :salary => 75000)
1738
- proj1 = devel.projects.build(:name => "Make bed")
1739
- proj2 = devel.projects.build(:name => "Lie in it")
1740
- assert_equal devel.projects.last, proj2
1741
- assert proj2.new_record?
1742
- devel.save
1743
- assert !devel.new_record?
1744
- assert !proj2.new_record?
1745
- assert_equal devel.projects.last, proj2
1746
- assert_equal Developer.find_by_name("Marcel").projects.last, proj2 # prove join table is updated
1747
- end
1748
-
1749
- def test_create
1750
- devel = Developer.find(1)
1751
- proj = devel.projects.create("name" => "Projekt")
1752
- assert_equal devel.projects.last, proj
1753
- assert !proj.new_record?
1754
- assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated
1755
- end
1756
-
1757
- def test_create_by_new_record
1758
- devel = Developer.new(:name => "Marcel", :salary => 75000)
1759
- proj1 = devel.projects.build(:name => "Make bed")
1760
- proj2 = devel.projects.build(:name => "Lie in it")
1761
- assert_equal devel.projects.last, proj2
1762
- assert proj2.new_record?
1763
- devel.save
1764
- assert !devel.new_record?
1765
- assert !proj2.new_record?
1766
- assert_equal devel.projects.last, proj2
1767
- assert_equal Developer.find_by_name("Marcel").projects.last, proj2 # prove join table is updated
1768
- end
1769
-
1770
- def test_uniq_after_the_fact
1771
- developers(:jamis).projects << projects(:active_record)
1772
- developers(:jamis).projects << projects(:active_record)
1773
- assert_equal 3, developers(:jamis).projects.size
1774
- assert_equal 1, developers(:jamis).projects.uniq.size
1775
- end
1776
-
1777
- def test_uniq_before_the_fact
1778
- projects(:active_record).developers << developers(:jamis)
1779
- projects(:active_record).developers << developers(:david)
1780
- assert_equal 3, projects(:active_record, :reload).developers.size
1781
- end
1782
-
1783
- def test_deleting
1784
- david = Developer.find(1)
1785
- active_record = Project.find(1)
1786
- david.projects.reload
1787
- assert_equal 2, david.projects.size
1788
- assert_equal 3, active_record.developers.size
1789
-
1790
- david.projects.delete(active_record)
1791
-
1792
- assert_equal 1, david.projects.size
1793
- assert_equal 1, david.projects(true).size
1794
- assert_equal 2, active_record.developers(true).size
1795
- end
1796
-
1797
- def test_deleting_array
1798
- david = Developer.find(1)
1799
- david.projects.reload
1800
- david.projects.delete(Project.find(:all))
1801
- assert_equal 0, david.projects.size
1802
- assert_equal 0, david.projects(true).size
1803
- end
1804
-
1805
- def test_deleting_with_sql
1806
- david = Developer.find(1)
1807
- active_record = Project.find(1)
1808
- active_record.developers.reload
1809
- assert_equal 3, active_record.developers_by_sql.size
1810
-
1811
- active_record.developers_by_sql.delete(david)
1812
- assert_equal 2, active_record.developers_by_sql(true).size
1813
- end
1814
-
1815
- def test_deleting_array_with_sql
1816
- active_record = Project.find(1)
1817
- active_record.developers.reload
1818
- assert_equal 3, active_record.developers_by_sql.size
1819
-
1820
- active_record.developers_by_sql.delete(Developer.find(:all))
1821
- assert_equal 0, active_record.developers_by_sql(true).size
1822
- end
1823
-
1824
- def test_deleting_all
1825
- david = Developer.find(1)
1826
- david.projects.reload
1827
- david.projects.clear
1828
- assert_equal 0, david.projects.size
1829
- assert_equal 0, david.projects(true).size
1830
- end
1831
-
1832
- def test_removing_associations_on_destroy
1833
- david = DeveloperWithBeforeDestroyRaise.find(1)
1834
- assert !david.projects.empty?
1835
- assert_nothing_raised { david.destroy }
1836
- assert david.projects.empty?
1837
- assert DeveloperWithBeforeDestroyRaise.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = 1").empty?
1838
- end
1839
-
1840
- def test_additional_columns_from_join_table
1841
- assert_date_from_db Date.new(2004, 10, 10), Developer.find(1).projects.first.joined_on.to_date
1842
- end
1843
-
1844
- def test_destroy_all
1845
- david = Developer.find(1)
1846
- david.projects.reload
1847
- assert !david.projects.empty?
1848
- david.projects.destroy_all
1849
- assert david.projects.empty?
1850
- assert david.projects(true).empty?
1851
- end
1852
-
1853
- def test_deprecated_push_with_attributes_was_removed
1854
- jamis = developers(:jamis)
1855
- assert_raise(NoMethodError) do
1856
- jamis.projects.push_with_attributes(projects(:action_controller), :joined_on => Date.today)
1857
- end
1858
- end
1859
-
1860
- def test_associations_with_conditions
1861
- assert_equal 3, projects(:active_record).developers.size
1862
- assert_equal 1, projects(:active_record).developers_named_david.size
1863
- assert_equal 1, projects(:active_record).developers_named_david_with_hash_conditions.size
1864
-
1865
- assert_equal developers(:david), projects(:active_record).developers_named_david.find(developers(:david).id)
1866
- assert_equal developers(:david), projects(:active_record).developers_named_david_with_hash_conditions.find(developers(:david).id)
1867
- assert_equal developers(:david), projects(:active_record).salaried_developers.find(developers(:david).id)
1868
-
1869
- projects(:active_record).developers_named_david.clear
1870
- assert_equal 2, projects(:active_record, :reload).developers.size
1871
- end
1872
-
1873
- def test_find_in_association
1874
- # Using sql
1875
- assert_equal developers(:david), projects(:active_record).developers.find(developers(:david).id), "SQL find"
1876
-
1877
- # Using ruby
1878
- active_record = projects(:active_record)
1879
- active_record.developers.reload
1880
- assert_equal developers(:david), active_record.developers.find(developers(:david).id), "Ruby find"
1881
- end
1882
-
1883
- def test_find_in_association_with_custom_finder_sql
1884
- assert_equal developers(:david), projects(:active_record).developers_with_finder_sql.find(developers(:david).id), "SQL find"
1885
-
1886
- active_record = projects(:active_record)
1887
- active_record.developers_with_finder_sql.reload
1888
- assert_equal developers(:david), active_record.developers_with_finder_sql.find(developers(:david).id), "Ruby find"
1889
- end
1890
-
1891
- def test_find_in_association_with_custom_finder_sql_and_string_id
1892
- assert_equal developers(:david), projects(:active_record).developers_with_finder_sql.find(developers(:david).id.to_s), "SQL find"
1893
- end
1894
-
1895
- def test_find_with_merged_options
1896
- assert_equal 1, projects(:active_record).limited_developers.size
1897
- assert_equal 1, projects(:active_record).limited_developers.find(:all).size
1898
- assert_equal 3, projects(:active_record).limited_developers.find(:all, :limit => nil).size
1899
- end
1900
-
1901
- def test_dynamic_find_should_respect_association_order
1902
- # Developers are ordered 'name DESC, id DESC'
1903
- low_id_jamis = developers(:jamis)
1904
- middle_id_jamis = developers(:poor_jamis)
1905
- high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis')
1906
-
1907
- assert_equal high_id_jamis, projects(:active_record).developers.find(:first, :conditions => "name = 'Jamis'")
1908
- assert_equal high_id_jamis, projects(:active_record).developers.find_by_name('Jamis')
1909
- end
1910
-
1911
- def test_dynamic_find_order_should_override_association_order
1912
- # Developers are ordered 'name DESC, id DESC'
1913
- low_id_jamis = developers(:jamis)
1914
- middle_id_jamis = developers(:poor_jamis)
1915
- high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis')
1916
-
1917
- assert_equal low_id_jamis, projects(:active_record).developers.find(:first, :conditions => "name = 'Jamis'", :order => 'id')
1918
- assert_equal low_id_jamis, projects(:active_record).developers.find_by_name('Jamis', :order => 'id')
1919
- end
1920
-
1921
- def test_dynamic_find_all_should_respect_association_order
1922
- # Developers are ordered 'name DESC, id DESC'
1923
- low_id_jamis = developers(:jamis)
1924
- middle_id_jamis = developers(:poor_jamis)
1925
- high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis')
1926
-
1927
- assert_equal [high_id_jamis, middle_id_jamis, low_id_jamis], projects(:active_record).developers.find(:all, :conditions => "name = 'Jamis'")
1928
- assert_equal [high_id_jamis, middle_id_jamis, low_id_jamis], projects(:active_record).developers.find_all_by_name('Jamis')
1929
- end
1930
-
1931
- def test_dynamic_find_all_order_should_override_association_order
1932
- # Developers are ordered 'name DESC, id DESC'
1933
- low_id_jamis = developers(:jamis)
1934
- middle_id_jamis = developers(:poor_jamis)
1935
- high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis')
1936
-
1937
- assert_equal [low_id_jamis, middle_id_jamis, high_id_jamis], projects(:active_record).developers.find(:all, :conditions => "name = 'Jamis'", :order => 'id')
1938
- assert_equal [low_id_jamis, middle_id_jamis, high_id_jamis], projects(:active_record).developers.find_all_by_name('Jamis', :order => 'id')
1939
- end
1940
-
1941
- def test_dynamic_find_all_should_respect_association_limit
1942
- assert_equal 1, projects(:active_record).limited_developers.find(:all, :conditions => "name = 'Jamis'").length
1943
- assert_equal 1, projects(:active_record).limited_developers.find_all_by_name('Jamis').length
1944
- end
1945
-
1946
- def test_dynamic_find_all_order_should_override_association_limit
1947
- assert_equal 2, projects(:active_record).limited_developers.find(:all, :conditions => "name = 'Jamis'", :limit => 9_000).length
1948
- assert_equal 2, projects(:active_record).limited_developers.find_all_by_name('Jamis', :limit => 9_000).length
1949
- end
1950
-
1951
- def test_new_with_values_in_collection
1952
- jamis = DeveloperForProjectWithAfterCreateHook.find_by_name('Jamis')
1953
- david = DeveloperForProjectWithAfterCreateHook.find_by_name('David')
1954
- project = ProjectWithAfterCreateHook.new(:name => "Cooking with Bertie")
1955
- project.developers << jamis
1956
- project.save!
1957
- project.reload
1958
-
1959
- assert project.developers.include?(jamis)
1960
- assert project.developers.include?(david)
1961
- end
1962
-
1963
- def test_find_in_association_with_options
1964
- developers = projects(:active_record).developers.find(:all)
1965
- assert_equal 3, developers.size
1966
-
1967
- assert_equal developers(:poor_jamis), projects(:active_record).developers.find(:first, :conditions => "salary < 10000")
1968
- assert_equal developers(:jamis), projects(:active_record).developers.find(:first, :order => "salary DESC")
1969
- end
1970
-
1971
- def test_replace_with_less
1972
- david = developers(:david)
1973
- david.projects = [projects(:action_controller)]
1974
- assert david.save
1975
- assert_equal 1, david.projects.length
1976
- end
1977
-
1978
- def test_replace_with_new
1979
- david = developers(:david)
1980
- david.projects = [projects(:action_controller), Project.new("name" => "ActionWebSearch")]
1981
- david.save
1982
- assert_equal 2, david.projects.length
1983
- assert !david.projects.include?(projects(:active_record))
1984
- end
1985
-
1986
- def test_replace_on_new_object
1987
- new_developer = Developer.new("name" => "Matz")
1988
- new_developer.projects = [projects(:action_controller), Project.new("name" => "ActionWebSearch")]
1989
- new_developer.save
1990
- assert_equal 2, new_developer.projects.length
1991
- end
1992
-
1993
- def test_consider_type
1994
- developer = Developer.find(:first)
1995
- special_project = SpecialProject.create("name" => "Special Project")
1996
-
1997
- other_project = developer.projects.first
1998
- developer.special_projects << special_project
1999
- developer.reload
2000
-
2001
- assert developer.projects.include?(special_project)
2002
- assert developer.special_projects.include?(special_project)
2003
- assert !developer.special_projects.include?(other_project)
2004
- end
2005
-
2006
- def test_update_attributes_after_push_without_duplicate_join_table_rows
2007
- developer = Developer.new("name" => "Kano")
2008
- project = SpecialProject.create("name" => "Special Project")
2009
- assert developer.save
2010
- developer.projects << project
2011
- developer.update_attribute("name", "Bruza")
2012
- assert_equal 1, Developer.connection.select_value(<<-end_sql).to_i
2013
- SELECT count(*) FROM developers_projects
2014
- WHERE project_id = #{project.id}
2015
- AND developer_id = #{developer.id}
2016
- end_sql
2017
- end
2018
-
2019
- def test_updating_attributes_on_non_rich_associations
2020
- welcome = categories(:technology).posts.first
2021
- welcome.title = "Something else"
2022
- assert welcome.save!
2023
- end
2024
-
2025
- def test_habtm_respects_select
2026
- categories(:technology).select_testing_posts(true).each do |o|
2027
- assert_respond_to o, :correctness_marker
2028
- end
2029
- assert_respond_to categories(:technology).select_testing_posts.find(:first), :correctness_marker
2030
- end
2031
-
2032
- def test_updating_attributes_on_rich_associations
2033
- david = projects(:action_controller).developers.first
2034
- david.name = "DHH"
2035
- assert_raises(ActiveRecord::ReadOnlyRecord) { david.save! }
2036
- end
2037
-
2038
- def test_updating_attributes_on_rich_associations_with_limited_find_from_reflection
2039
- david = projects(:action_controller).selected_developers.first
2040
- david.name = "DHH"
2041
- assert_nothing_raised { david.save! }
2042
- end
2043
-
2044
-
2045
- def test_updating_attributes_on_rich_associations_with_limited_find
2046
- david = projects(:action_controller).developers.find(:all, :select => "developers.*").first
2047
- david.name = "DHH"
2048
- assert david.save!
2049
- end
2050
-
2051
- def test_join_table_alias
2052
- assert_equal 3, Developer.find(:all, :include => {:projects => :developers}, :conditions => 'developers_projects_join.joined_on IS NOT NULL').size
2053
- end
2054
-
2055
- def test_join_with_group
2056
- group = Developer.columns.inject([]) do |g, c|
2057
- g << "developers.#{c.name}"
2058
- g << "developers_projects_2.#{c.name}"
2059
- end
2060
- Project.columns.each { |c| group << "projects.#{c.name}" }
2061
-
2062
- assert_equal 3, Developer.find(:all, :include => {:projects => :developers}, :conditions => 'developers_projects_join.joined_on IS NOT NULL', :group => group.join(",")).size
2063
- end
2064
-
2065
- def test_get_ids
2066
- assert_equal projects(:active_record, :action_controller).map(&:id).sort, developers(:david).project_ids.sort
2067
- assert_equal [projects(:active_record).id], developers(:jamis).project_ids
2068
- end
2069
-
2070
- def test_assign_ids
2071
- developer = Developer.new("name" => "Joe")
2072
- developer.project_ids = projects(:active_record, :action_controller).map(&:id)
2073
- developer.save
2074
- developer.reload
2075
- assert_equal 2, developer.projects.length
2076
- assert_equal projects(:active_record), developer.projects[0]
2077
- assert_equal projects(:action_controller), developer.projects[1]
2078
- end
2079
-
2080
- def test_assign_ids_ignoring_blanks
2081
- developer = Developer.new("name" => "Joe")
2082
- developer.project_ids = [projects(:active_record).id, nil, projects(:action_controller).id, '']
2083
- developer.save
2084
- developer.reload
2085
- assert_equal 2, developer.projects.length
2086
- assert_equal projects(:active_record), developer.projects[0]
2087
- assert_equal projects(:action_controller), developer.projects[1]
2088
- end
2089
-
2090
- def test_select_limited_ids_list
2091
- # Set timestamps
2092
- Developer.transaction do
2093
- Developer.find(:all, :order => 'id').each_with_index do |record, i|
2094
- record.update_attributes(:created_at => 5.years.ago + (i * 5.minutes))
2095
- end
2096
- end
2097
-
2098
- join_base = ActiveRecord::Associations::ClassMethods::JoinDependency::JoinBase.new(Project)
2099
- join_dep = ActiveRecord::Associations::ClassMethods::JoinDependency.new(join_base, :developers, nil)
2100
- projects = Project.send(:select_limited_ids_list, {:order => 'developers.created_at'}, join_dep)
2101
- assert !projects.include?("'"), projects
2102
- assert_equal %w(1 2), projects.scan(/\d/).sort
2103
- end
2104
-
2105
- def test_scoped_find_on_through_association_doesnt_return_read_only_records
2106
- tag = Post.find(1).tags.find_by_name("General")
2107
-
2108
- assert_nothing_raised do
2109
- tag.save!
2110
- end
2111
- end
2112
- end
2113
-
2114
-
2115
- class OverridingAssociationsTest < Test::Unit::TestCase
2116
- class Person < ActiveRecord::Base; end
2117
- class DifferentPerson < ActiveRecord::Base; end
2118
-
2119
- class PeopleList < ActiveRecord::Base
2120
- has_and_belongs_to_many :has_and_belongs_to_many, :before_add => :enlist
2121
- has_many :has_many, :before_add => :enlist
2122
- belongs_to :belongs_to
2123
- has_one :has_one
2124
- end
2125
-
2126
- class DifferentPeopleList < PeopleList
2127
- # Different association with the same name, callbacks should be omitted here.
2128
- has_and_belongs_to_many :has_and_belongs_to_many, :class_name => 'DifferentPerson'
2129
- has_many :has_many, :class_name => 'DifferentPerson'
2130
- belongs_to :belongs_to, :class_name => 'DifferentPerson'
2131
- has_one :has_one, :class_name => 'DifferentPerson'
2132
- end
2133
-
2134
- def test_habtm_association_redefinition_callbacks_should_differ_and_not_inherited
2135
- # redeclared association on AR descendant should not inherit callbacks from superclass
2136
- callbacks = PeopleList.read_inheritable_attribute(:before_add_for_has_and_belongs_to_many)
2137
- assert_equal([:enlist], callbacks)
2138
- callbacks = DifferentPeopleList.read_inheritable_attribute(:before_add_for_has_and_belongs_to_many)
2139
- assert_equal([], callbacks)
2140
- end
2141
-
2142
- def test_has_many_association_redefinition_callbacks_should_differ_and_not_inherited
2143
- # redeclared association on AR descendant should not inherit callbacks from superclass
2144
- callbacks = PeopleList.read_inheritable_attribute(:before_add_for_has_many)
2145
- assert_equal([:enlist], callbacks)
2146
- callbacks = DifferentPeopleList.read_inheritable_attribute(:before_add_for_has_many)
2147
- assert_equal([], callbacks)
2148
- end
2149
-
2150
- def test_habtm_association_redefinition_reflections_should_differ_and_not_inherited
2151
- assert_not_equal(
2152
- PeopleList.reflect_on_association(:has_and_belongs_to_many),
2153
- DifferentPeopleList.reflect_on_association(:has_and_belongs_to_many)
2154
- )
2155
- end
2156
-
2157
- def test_has_many_association_redefinition_reflections_should_differ_and_not_inherited
2158
- assert_not_equal(
2159
- PeopleList.reflect_on_association(:has_many),
2160
- DifferentPeopleList.reflect_on_association(:has_many)
2161
- )
2162
- end
2163
-
2164
- def test_belongs_to_association_redefinition_reflections_should_differ_and_not_inherited
2165
- assert_not_equal(
2166
- PeopleList.reflect_on_association(:belongs_to),
2167
- DifferentPeopleList.reflect_on_association(:belongs_to)
2168
- )
2169
- end
2170
-
2171
- def test_has_one_association_redefinition_reflections_should_differ_and_not_inherited
2172
- assert_not_equal(
2173
- PeopleList.reflect_on_association(:has_one),
2174
- DifferentPeopleList.reflect_on_association(:has_one)
2175
- )
2176
- end
2177
- end