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
File without changes
File without changes
File without changes
@@ -2,25 +2,28 @@ class Category < ActiveRecord::Base
2
2
  has_and_belongs_to_many :posts
3
3
  has_and_belongs_to_many :special_posts, :class_name => "Post"
4
4
  has_and_belongs_to_many :other_posts, :class_name => "Post"
5
-
5
+
6
6
  has_and_belongs_to_many(:select_testing_posts,
7
7
  :class_name => 'Post',
8
8
  :foreign_key => 'category_id',
9
9
  :association_foreign_key => 'post_id',
10
10
  :select => 'posts.*, 1 as correctness_marker')
11
11
 
12
+ has_and_belongs_to_many :post_with_conditions,
13
+ :class_name => 'Post',
14
+ :conditions => { :title => 'Yet Another Testing Title' }
12
15
  def self.what_are_you
13
16
  'a category...'
14
17
  end
15
-
18
+
16
19
  has_many :categorizations
17
20
  has_many :authors, :through => :categorizations, :select => 'authors.*, categorizations.post_id'
18
21
  end
19
22
 
20
23
  class SpecialCategory < Category
21
-
24
+
22
25
  def self.what_are_you
23
26
  'a special category...'
24
- end
25
-
27
+ end
28
+
26
29
  end
File without changes
@@ -0,0 +1,7 @@
1
+ class Club < ActiveRecord::Base
2
+ has_many :memberships
3
+ has_many :members, :through => :memberships
4
+ has_many :current_memberships
5
+ has_one :sponsor
6
+ has_one :sponsored_member, :through => :sponsor, :source => :sponsorable, :source_type => "Member"
7
+ end
File without changes
@@ -1,10 +1,12 @@
1
1
  class Comment < ActiveRecord::Base
2
- belongs_to :post
2
+ named_scope :containing_the_letter_e, :conditions => "comments.body LIKE '%e%'"
3
3
 
4
+ belongs_to :post, :counter_cache => true
5
+
4
6
  def self.what_are_you
5
7
  'a comment...'
6
8
  end
7
-
9
+
8
10
  def self.search_by_type(q)
9
11
  self.find(:all, :conditions => ["#{QUOTED_TYPE} = ?", q])
10
12
  end
@@ -20,4 +22,4 @@ class VerySpecialComment < Comment
20
22
  def self.what_are_you
21
23
  'a very special comment...'
22
24
  end
23
- end
25
+ end
@@ -9,12 +9,16 @@ class Company < AbstractCompany
9
9
  validates_presence_of :name
10
10
 
11
11
  has_one :dummy_account, :foreign_key => "firm_id", :class_name => "Account"
12
-
12
+
13
13
  def arbitrary_method
14
14
  "I am Jack's profound disappointment"
15
15
  end
16
16
  end
17
17
 
18
+ module Namespaced
19
+ class Company < ::Company
20
+ end
21
+ end
18
22
 
19
23
  class Firm < Company
20
24
  has_many :clients, :order => "id", :dependent => :destroy, :counter_sql =>
@@ -40,8 +44,11 @@ class Firm < Company
40
44
  :counter_sql => 'SELECT COUNT(*) FROM companies WHERE client_of = 1000'
41
45
  has_many :clients_using_finder_sql, :class_name => "Client", :finder_sql => 'SELECT * FROM companies WHERE 1=1'
42
46
  has_many :plain_clients, :class_name => 'Client'
47
+ has_many :readonly_clients, :class_name => 'Client', :readonly => true
43
48
 
44
49
  has_one :account, :foreign_key => "firm_id", :dependent => :destroy
50
+ has_one :account_with_select, :foreign_key => "firm_id", :select => "id, firm_id", :class_name=>'Account'
51
+ has_one :readonly_account, :foreign_key => "firm_id", :class_name => "Account", :readonly => true
45
52
  end
46
53
 
47
54
  class DependentFirm < Company
@@ -58,8 +65,10 @@ end
58
65
  class Client < Company
59
66
  belongs_to :firm, :foreign_key => "client_of"
60
67
  belongs_to :firm_with_basic_id, :class_name => "Firm", :foreign_key => "firm_id"
68
+ belongs_to :firm_with_select, :class_name => "Firm", :foreign_key => "firm_id", :select => "id"
61
69
  belongs_to :firm_with_other_name, :class_name => "Firm", :foreign_key => "client_of"
62
70
  belongs_to :firm_with_condition, :class_name => "Firm", :foreign_key => "client_of", :conditions => ["1 = ?", 1]
71
+ belongs_to :readonly_firm, :class_name => "Firm", :foreign_key => "firm_id", :readonly => true
63
72
 
64
73
  # Record destruction so we can test whether firm.clients.clear has
65
74
  # is calling client.destroy, deleting from the database, or setting
@@ -74,12 +83,12 @@ class Client < Company
74
83
  end
75
84
  true
76
85
  end
77
-
86
+
78
87
  # Used to test that read and question methods are not generated for these attributes
79
88
  def ruby_type
80
89
  read_attribute :ruby_type
81
90
  end
82
-
91
+
83
92
  def rating?
84
93
  query_attribute :rating
85
94
  end
@@ -94,7 +103,7 @@ end
94
103
 
95
104
  class Account < ActiveRecord::Base
96
105
  belongs_to :firm
97
-
106
+
98
107
  def self.destroyed_account_ids
99
108
  @destroyed_account_ids ||= Hash.new { |h,k| h[k] = [] }
100
109
  end
@@ -105,8 +114,8 @@ class Account < ActiveRecord::Base
105
114
  end
106
115
  true
107
116
  end
108
-
109
-
117
+
118
+
110
119
  protected
111
120
  def validate
112
121
  errors.add_on_empty "credit_limit"
@@ -3,7 +3,7 @@ module MyApplication
3
3
  class Company < ActiveRecord::Base
4
4
  attr_protected :rating
5
5
  end
6
-
6
+
7
7
  class Firm < Company
8
8
  has_many :clients, :order => "id", :dependent => :destroy
9
9
  has_many :clients_sorted_desc, :class_name => "Client", :order => "id DESC"
@@ -17,13 +17,15 @@ module MyApplication
17
17
  class Client < Company
18
18
  belongs_to :firm, :foreign_key => "client_of"
19
19
  belongs_to :firm_with_other_name, :class_name => "Firm", :foreign_key => "client_of"
20
+
21
+ class Contact < ActiveRecord::Base; end
20
22
  end
21
-
23
+
22
24
  class Developer < ActiveRecord::Base
23
25
  has_and_belongs_to_many :projects
24
26
  validates_length_of :name, :within => (3..20)
25
27
  end
26
-
28
+
27
29
  class Project < ActiveRecord::Base
28
30
  has_and_belongs_to_many :developers
29
31
  end
@@ -1,4 +1,3 @@
1
1
  class Computer < ActiveRecord::Base
2
2
  belongs_to :developer, :foreign_key=>'developer'
3
3
  end
4
-
@@ -11,6 +11,6 @@ class Contact < ActiveRecord::Base
11
11
  column :created_at, :datetime
12
12
  column :awesome, :boolean
13
13
  column :preferences, :string
14
-
14
+
15
15
  serialize :preferences
16
16
  end
File without changes
@@ -10,25 +10,25 @@ class Address
10
10
  def initialize(street, city, country)
11
11
  @street, @city, @country = street, city, country
12
12
  end
13
-
13
+
14
14
  def close_to?(other_address)
15
15
  city == other_address.city && country == other_address.country
16
16
  end
17
17
 
18
18
  def ==(other)
19
19
  other.is_a?(self.class) && other.street == street && other.city == city && other.country == country
20
- end
20
+ end
21
21
  end
22
22
 
23
23
  class Money
24
24
  attr_reader :amount, :currency
25
-
25
+
26
26
  EXCHANGE_RATES = { "USD_TO_DKK" => 6, "DKK_TO_USD" => 0.6 }
27
-
27
+
28
28
  def initialize(amount, currency = "USD")
29
29
  @amount, @currency = amount, currency
30
30
  end
31
-
31
+
32
32
  def exchange_to(other_currency)
33
33
  Money.new((amount * EXCHANGE_RATES["#{currency}_TO_#{other_currency}"]).floor, other_currency)
34
34
  end
@@ -36,15 +36,15 @@ end
36
36
 
37
37
  class GpsLocation
38
38
  attr_reader :gps_location
39
-
39
+
40
40
  def initialize(gps_location)
41
41
  @gps_location = gps_location
42
42
  end
43
-
43
+
44
44
  def latitude
45
45
  gps_location.split("x").first
46
46
  end
47
-
47
+
48
48
  def longitude
49
49
  gps_location.split("x").last
50
50
  end
File without changes
@@ -16,22 +16,22 @@ class Developer < ActiveRecord::Base
16
16
  find(:first, :order => "id DESC")
17
17
  end
18
18
  end
19
-
20
- has_and_belongs_to_many :projects_extended_by_name,
21
- :class_name => "Project",
22
- :join_table => "developers_projects",
19
+
20
+ has_and_belongs_to_many :projects_extended_by_name,
21
+ :class_name => "Project",
22
+ :join_table => "developers_projects",
23
23
  :association_foreign_key => "project_id",
24
24
  :extend => DeveloperProjectsAssociationExtension
25
25
 
26
- has_and_belongs_to_many :projects_extended_by_name_twice,
27
- :class_name => "Project",
28
- :join_table => "developers_projects",
26
+ has_and_belongs_to_many :projects_extended_by_name_twice,
27
+ :class_name => "Project",
28
+ :join_table => "developers_projects",
29
29
  :association_foreign_key => "project_id",
30
30
  :extend => [DeveloperProjectsAssociationExtension, DeveloperProjectsAssociationExtension2]
31
31
 
32
- has_and_belongs_to_many :projects_extended_by_name_and_block,
33
- :class_name => "Project",
34
- :join_table => "developers_projects",
32
+ has_and_belongs_to_many :projects_extended_by_name_and_block,
33
+ :class_name => "Project",
34
+ :join_table => "developers_projects",
35
35
  :association_foreign_key => "project_id",
36
36
  :extend => DeveloperProjectsAssociationExtension do
37
37
  def find_least_recent
@@ -49,6 +49,10 @@ class Developer < ActiveRecord::Base
49
49
  before_create do |developer|
50
50
  developer.audit_logs.build :message => "Computer created"
51
51
  end
52
+
53
+ def log=(message)
54
+ audit_logs.build :message => message
55
+ end
52
56
  end
53
57
 
54
58
  class AuditLog < ActiveRecord::Base
File without changes
File without changes
@@ -0,0 +1,2 @@
1
+ class Guid < ActiveRecord::Base
2
+ end
File without changes
@@ -0,0 +1,5 @@
1
+ class Job < ActiveRecord::Base
2
+ has_many :references
3
+ has_many :people, :through => :references
4
+ belongs_to :ideal_reference, :class_name => 'Reference'
5
+ end
File without changes
File without changes
File without changes
@@ -0,0 +1,9 @@
1
+ class Member < ActiveRecord::Base
2
+ has_one :current_membership
3
+ has_many :memberships
4
+ has_many :fellow_members, :through => :club, :source => :members
5
+ has_one :club, :through => :current_membership
6
+ has_one :favourite_club, :through => :memberships, :conditions => ["memberships.favourite = ?", true], :source => :club
7
+ has_one :sponsor, :as => :sponsorable
8
+ has_one :sponsor_club, :through => :sponsor
9
+ end
@@ -0,0 +1,9 @@
1
+ class Membership < ActiveRecord::Base
2
+ belongs_to :member
3
+ belongs_to :club
4
+ end
5
+
6
+ class CurrentMembership < Membership
7
+ belongs_to :member
8
+ belongs_to :club
9
+ end
File without changes
@@ -1,4 +1,4 @@
1
1
  class Order < ActiveRecord::Base
2
- belongs_to :billing, :class_name => 'Customer', :foreign_key => 'billing_customer_id'
3
- belongs_to :shipping, :class_name => 'Customer', :foreign_key => 'shipping_customer_id'
2
+ belongs_to :billing, :class_name => 'Customer', :foreign_key => 'billing_customer_id'
3
+ belongs_to :shipping, :class_name => 'Customer', :foreign_key => 'shipping_customer_id'
4
4
  end
@@ -0,0 +1,4 @@
1
+ class Owner < ActiveRecord::Base
2
+ set_primary_key :owner_id
3
+ has_many :pets
4
+ end
File without changes
@@ -0,0 +1,10 @@
1
+ class Person < ActiveRecord::Base
2
+ has_many :readers
3
+ has_many :posts, :through => :readers
4
+ has_many :posts_with_no_comments, :through => :readers, :source => :post, :include => :comments, :conditions => 'comments.id is null'
5
+
6
+ has_many :references
7
+ has_many :jobs, :through => :references
8
+ has_one :favourite_reference, :class_name => 'Reference', :conditions => ['favourite=?', true]
9
+
10
+ end
@@ -0,0 +1,4 @@
1
+ class Pet < ActiveRecord::Base
2
+ set_primary_key :pet_id
3
+ belongs_to :owner
4
+ end
@@ -0,0 +1,9 @@
1
+ class Pirate < ActiveRecord::Base
2
+ belongs_to :parrot
3
+ has_and_belongs_to_many :parrots
4
+ has_many :treasures, :as => :looter
5
+
6
+ has_many :treasure_estimates, :through => :treasures, :source => :price_estimates
7
+
8
+ validates_presence_of :catchphrase
9
+ end
@@ -1,4 +1,6 @@
1
1
  class Post < ActiveRecord::Base
2
+ named_scope :containing_the_letter_a, :conditions => "body LIKE '%a%'"
3
+
2
4
  belongs_to :author do
3
5
  def greeting
4
6
  "hello"
@@ -7,12 +9,17 @@ class Post < ActiveRecord::Base
7
9
 
8
10
  belongs_to :author_with_posts, :class_name => "Author", :foreign_key => :author_id, :include => :posts
9
11
 
12
+ has_one :last_comment, :class_name => 'Comment', :order => 'id desc'
13
+
10
14
  has_many :comments, :order => "body" do
11
15
  def find_most_recent
12
16
  find(:first, :order => "id DESC")
13
17
  end
14
18
  end
15
19
 
20
+ has_many :comments_with_interpolated_conditions, :class_name => 'Comment',
21
+ :conditions => ['#{"#{aliased_table_name}." rescue ""}body = ?', 'Thank you for the welcome']
22
+
16
23
  has_one :very_special_comment
17
24
  has_one :very_special_comment_with_post, :class_name => "VerySpecialComment", :include => :post
18
25
  has_many :special_comments
@@ -22,13 +29,13 @@ class Post < ActiveRecord::Base
22
29
  has_and_belongs_to_many :special_categories, :join_table => "categories_posts", :association_foreign_key => 'category_id'
23
30
 
24
31
  has_many :taggings, :as => :taggable
25
- has_many :tags, :through => :taggings, :include => :tagging do
32
+ has_many :tags, :through => :taggings do
26
33
  def add_joins_and_select
27
34
  find :all, :select => 'tags.*, authors.id as author_id', :include => false,
28
35
  :joins => 'left outer join posts on taggings.taggable_id = posts.id left outer join authors on posts.author_id = authors.id'
29
36
  end
30
37
  end
31
-
38
+
32
39
  has_many :funky_tags, :through => :taggings, :source => :tag
33
40
  has_many :super_tags, :through => :taggings
34
41
  has_one :tagging, :as => :taggable
@@ -41,6 +48,20 @@ class Post < ActiveRecord::Base
41
48
 
42
49
  has_many :readers
43
50
  has_many :people, :through => :readers
51
+ has_many :people_with_callbacks, :source=>:person, :through => :readers,
52
+ :before_add => lambda {|owner, reader| log(:added, :before, reader.first_name) },
53
+ :after_add => lambda {|owner, reader| log(:added, :after, reader.first_name) },
54
+ :before_remove => lambda {|owner, reader| log(:removed, :before, reader.first_name) },
55
+ :after_remove => lambda {|owner, reader| log(:removed, :after, reader.first_name) }
56
+
57
+ def self.reset_log
58
+ @log = []
59
+ end
60
+
61
+ def self.log(message=nil, side=nil, new_record=nil)
62
+ return @log if message.nil?
63
+ @log << [message, side, new_record]
64
+ end
44
65
 
45
66
  def self.what_are_you
46
67
  'a post...'