ferblape-query_memcached 2.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. data/.gitignore +2 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.markdown +87 -0
  4. data/RUNNING_TESTS +18 -0
  5. data/Rakefile +37 -0
  6. data/TODO +6 -0
  7. data/init.rb +3 -0
  8. data/lib/extensions/lock.rb +31 -0
  9. data/lib/query_memcached.rb +191 -0
  10. data/test/query_memcached_test.rb +26 -0
  11. data/test/testing_app/README +1 -0
  12. data/test/testing_app/Rakefile +8 -0
  13. data/test/testing_app/app/controllers/application.rb +15 -0
  14. data/test/testing_app/app/helpers/application_helper.rb +3 -0
  15. data/test/testing_app/app/models/author.rb +133 -0
  16. data/test/testing_app/app/models/auto_id.rb +4 -0
  17. data/test/testing_app/app/models/binary.rb +2 -0
  18. data/test/testing_app/app/models/book.rb +4 -0
  19. data/test/testing_app/app/models/categorization.rb +5 -0
  20. data/test/testing_app/app/models/category.rb +29 -0
  21. data/test/testing_app/app/models/citation.rb +6 -0
  22. data/test/testing_app/app/models/club.rb +7 -0
  23. data/test/testing_app/app/models/column_name.rb +3 -0
  24. data/test/testing_app/app/models/comment.rb +25 -0
  25. data/test/testing_app/app/models/company.rb +123 -0
  26. data/test/testing_app/app/models/company_in_module.rb +61 -0
  27. data/test/testing_app/app/models/computer.rb +4 -0
  28. data/test/testing_app/app/models/contact.rb +16 -0
  29. data/test/testing_app/app/models/course.rb +3 -0
  30. data/test/testing_app/app/models/customer.rb +55 -0
  31. data/test/testing_app/app/models/default.rb +2 -0
  32. data/test/testing_app/app/models/developer.rb +76 -0
  33. data/test/testing_app/app/models/edge.rb +5 -0
  34. data/test/testing_app/app/models/entrant.rb +3 -0
  35. data/test/testing_app/app/models/guid.rb +2 -0
  36. data/test/testing_app/app/models/item.rb +7 -0
  37. data/test/testing_app/app/models/job.rb +5 -0
  38. data/test/testing_app/app/models/joke.rb +3 -0
  39. data/test/testing_app/app/models/keyboard.rb +3 -0
  40. data/test/testing_app/app/models/legacy_thing.rb +3 -0
  41. data/test/testing_app/app/models/matey.rb +4 -0
  42. data/test/testing_app/app/models/member.rb +9 -0
  43. data/test/testing_app/app/models/membership.rb +9 -0
  44. data/test/testing_app/app/models/minimalistic.rb +2 -0
  45. data/test/testing_app/app/models/mixed_case_monkey.rb +3 -0
  46. data/test/testing_app/app/models/movie.rb +5 -0
  47. data/test/testing_app/app/models/order.rb +4 -0
  48. data/test/testing_app/app/models/owner.rb +4 -0
  49. data/test/testing_app/app/models/parrot.rb +13 -0
  50. data/test/testing_app/app/models/person.rb +10 -0
  51. data/test/testing_app/app/models/pet.rb +4 -0
  52. data/test/testing_app/app/models/pirate.rb +9 -0
  53. data/test/testing_app/app/models/post.rb +80 -0
  54. data/test/testing_app/app/models/price_estimate.rb +3 -0
  55. data/test/testing_app/app/models/project.rb +29 -0
  56. data/test/testing_app/app/models/reader.rb +4 -0
  57. data/test/testing_app/app/models/reference.rb +4 -0
  58. data/test/testing_app/app/models/reply.rb +39 -0
  59. data/test/testing_app/app/models/ship.rb +3 -0
  60. data/test/testing_app/app/models/sponsor.rb +4 -0
  61. data/test/testing_app/app/models/subject.rb +4 -0
  62. data/test/testing_app/app/models/subscriber.rb +8 -0
  63. data/test/testing_app/app/models/subscription.rb +4 -0
  64. data/test/testing_app/app/models/tag.rb +7 -0
  65. data/test/testing_app/app/models/tagging.rb +10 -0
  66. data/test/testing_app/app/models/task.rb +2 -0
  67. data/test/testing_app/app/models/topic.rb +65 -0
  68. data/test/testing_app/app/models/treasure.rb +6 -0
  69. data/test/testing_app/app/models/vertex.rb +9 -0
  70. data/test/testing_app/app/models/warehouse_thing.rb +5 -0
  71. data/test/testing_app/config/boot.rb +109 -0
  72. data/test/testing_app/config/database.yml +11 -0
  73. data/test/testing_app/config/environment.rb +19 -0
  74. data/test/testing_app/config/environments/development.rb +0 -0
  75. data/test/testing_app/config/environments/production.rb +0 -0
  76. data/test/testing_app/config/environments/test.rb +0 -0
  77. data/test/testing_app/config/initializers/inflections.rb +10 -0
  78. data/test/testing_app/config/initializers/mime_types.rb +5 -0
  79. data/test/testing_app/config/initializers/new_rails_defaults.rb +15 -0
  80. data/test/testing_app/config/routes.rb +41 -0
  81. data/test/testing_app/db/schema.rb +443 -0
  82. data/test/testing_app/script/about +3 -0
  83. data/test/testing_app/script/console +3 -0
  84. data/test/testing_app/script/dbconsole +3 -0
  85. data/test/testing_app/script/destroy +3 -0
  86. data/test/testing_app/script/generate +3 -0
  87. data/test/testing_app/script/performance/benchmarker +3 -0
  88. data/test/testing_app/script/performance/profiler +3 -0
  89. data/test/testing_app/script/performance/request +3 -0
  90. data/test/testing_app/script/plugin +3 -0
  91. data/test/testing_app/script/process/inspector +3 -0
  92. data/test/testing_app/script/process/reaper +3 -0
  93. data/test/testing_app/script/process/spawner +3 -0
  94. data/test/testing_app/script/runner +3 -0
  95. data/test/testing_app/script/server +3 -0
  96. data/test/testing_app/test/fixtures/accounts.yml +28 -0
  97. data/test/testing_app/test/fixtures/all/developers.yml +0 -0
  98. data/test/testing_app/test/fixtures/all/people.csv +0 -0
  99. data/test/testing_app/test/fixtures/all/tasks.yml +0 -0
  100. data/test/testing_app/test/fixtures/author_addresses.yml +5 -0
  101. data/test/testing_app/test/fixtures/author_favorites.yml +4 -0
  102. data/test/testing_app/test/fixtures/authors.yml +9 -0
  103. data/test/testing_app/test/fixtures/binaries.yml +132 -0
  104. data/test/testing_app/test/fixtures/books.yml +7 -0
  105. data/test/testing_app/test/fixtures/categories.yml +14 -0
  106. data/test/testing_app/test/fixtures/categories/special_categories.yml +9 -0
  107. data/test/testing_app/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -0
  108. data/test/testing_app/test/fixtures/categories_posts.yml +23 -0
  109. data/test/testing_app/test/fixtures/categorizations.yml +17 -0
  110. data/test/testing_app/test/fixtures/clubs.yml +6 -0
  111. data/test/testing_app/test/fixtures/comments.yml +59 -0
  112. data/test/testing_app/test/fixtures/companies.yml +55 -0
  113. data/test/testing_app/test/fixtures/computers.yml +4 -0
  114. data/test/testing_app/test/fixtures/courses.yml +7 -0
  115. data/test/testing_app/test/fixtures/customers.yml +17 -0
  116. data/test/testing_app/test/fixtures/developers.yml +21 -0
  117. data/test/testing_app/test/fixtures/developers_projects.yml +17 -0
  118. data/test/testing_app/test/fixtures/edges.yml +6 -0
  119. data/test/testing_app/test/fixtures/entrants.yml +14 -0
  120. data/test/testing_app/test/fixtures/fk_test_has_fk.yml +3 -0
  121. data/test/testing_app/test/fixtures/fk_test_has_pk.yml +2 -0
  122. data/test/testing_app/test/fixtures/funny_jokes.yml +10 -0
  123. data/test/testing_app/test/fixtures/items.yml +4 -0
  124. data/test/testing_app/test/fixtures/jobs.yml +7 -0
  125. data/test/testing_app/test/fixtures/legacy_things.yml +3 -0
  126. data/test/testing_app/test/fixtures/mateys.yml +4 -0
  127. data/test/testing_app/test/fixtures/members.yml +4 -0
  128. data/test/testing_app/test/fixtures/memberships.yml +20 -0
  129. data/test/testing_app/test/fixtures/minimalistics.yml +2 -0
  130. data/test/testing_app/test/fixtures/mixed_case_monkeys.yml +6 -0
  131. data/test/testing_app/test/fixtures/mixins.yml +29 -0
  132. data/test/testing_app/test/fixtures/movies.yml +7 -0
  133. data/test/testing_app/test/fixtures/naked/csv/accounts.csv +1 -0
  134. data/test/testing_app/test/fixtures/naked/yml/accounts.yml +1 -0
  135. data/test/testing_app/test/fixtures/naked/yml/companies.yml +1 -0
  136. data/test/testing_app/test/fixtures/naked/yml/courses.yml +1 -0
  137. data/test/testing_app/test/fixtures/owners.yml +7 -0
  138. data/test/testing_app/test/fixtures/parrots.yml +27 -0
  139. data/test/testing_app/test/fixtures/parrots_pirates.yml +7 -0
  140. data/test/testing_app/test/fixtures/people.yml +6 -0
  141. data/test/testing_app/test/fixtures/pets.yml +14 -0
  142. data/test/testing_app/test/fixtures/pirates.yml +9 -0
  143. data/test/testing_app/test/fixtures/posts.yml +49 -0
  144. data/test/testing_app/test/fixtures/price_estimates.yml +7 -0
  145. data/test/testing_app/test/fixtures/projects.yml +7 -0
  146. data/test/testing_app/test/fixtures/readers.yml +9 -0
  147. data/test/testing_app/test/fixtures/references.yml +17 -0
  148. data/test/testing_app/test/fixtures/reserved_words/distinct.yml +5 -0
  149. data/test/testing_app/test/fixtures/reserved_words/distincts_selects.yml +11 -0
  150. data/test/testing_app/test/fixtures/reserved_words/group.yml +14 -0
  151. data/test/testing_app/test/fixtures/reserved_words/select.yml +8 -0
  152. data/test/testing_app/test/fixtures/reserved_words/values.yml +7 -0
  153. data/test/testing_app/test/fixtures/ships.yml +5 -0
  154. data/test/testing_app/test/fixtures/sponsors.yml +9 -0
  155. data/test/testing_app/test/fixtures/subscribers.yml +7 -0
  156. data/test/testing_app/test/fixtures/subscriptions.yml +12 -0
  157. data/test/testing_app/test/fixtures/taggings.yml +28 -0
  158. data/test/testing_app/test/fixtures/tags.yml +7 -0
  159. data/test/testing_app/test/fixtures/tasks.yml +7 -0
  160. data/test/testing_app/test/fixtures/topics.yml +42 -0
  161. data/test/testing_app/test/fixtures/treasures.yml +10 -0
  162. data/test/testing_app/test/fixtures/vertices.yml +4 -0
  163. data/test/testing_app/test/fixtures/warehouse-things.yml +3 -0
  164. data/test/testing_app/test/test_helper.rb +131 -0
  165. data/test/testing_app/test/unit/query_cache_test.rb +180 -0
  166. metadata +289 -0
@@ -0,0 +1,15 @@
1
+ # Filters added to this controller apply to all controllers in the application.
2
+ # Likewise, all the methods added will be available for all controllers.
3
+
4
+ class ApplicationController < ActionController::Base
5
+ helper :all # include all helpers, all the time
6
+
7
+ # See ActionController::RequestForgeryProtection for details
8
+ # Uncomment the :secret if you're not using the cookie session store
9
+ protect_from_forgery # :secret => '59cdc4dc50e7881541020d7eefef20f9'
10
+
11
+ # See ActionController::Base for details
12
+ # Uncomment this to filter the contents of submitted sensitive data parameters
13
+ # from your application log (in this case, all fields with names like "password").
14
+ # filter_parameter_logging :password
15
+ end
@@ -0,0 +1,3 @@
1
+ # Methods added to this helper will be available to all templates in the application.
2
+ module ApplicationHelper
3
+ end
@@ -0,0 +1,133 @@
1
+ class Author < ActiveRecord::Base
2
+ has_many :posts
3
+ has_many :posts_with_comments, :include => :comments, :class_name => "Post"
4
+ has_many :posts_with_categories, :include => :categories, :class_name => "Post"
5
+ has_many :posts_with_comments_and_categories, :include => [ :comments, :categories ], :order => "posts.id", :class_name => "Post"
6
+ has_many :posts_containing_the_letter_a, :class_name => "Post"
7
+ has_many :posts_with_extension, :class_name => "Post" do #, :extend => ProxyTestExtension
8
+ def testing_proxy_owner
9
+ proxy_owner
10
+ end
11
+ def testing_proxy_reflection
12
+ proxy_reflection
13
+ end
14
+ def testing_proxy_target
15
+ proxy_target
16
+ end
17
+ end
18
+ has_many :comments, :through => :posts
19
+ has_many :comments_containing_the_letter_e, :through => :posts, :source => :comments
20
+ has_many :comments_with_order_and_conditions, :through => :posts, :source => :comments, :order => 'comments.body', :conditions => "comments.body like 'Thank%'"
21
+ has_many :comments_with_include, :through => :posts, :source => :comments, :include => :post
22
+
23
+
24
+ has_many :comments_desc, :through => :posts, :source => :comments, :order => 'comments.id DESC'
25
+ has_many :limited_comments, :through => :posts, :source => :comments, :limit => 1
26
+ has_many :funky_comments, :through => :posts, :source => :comments
27
+ has_many :ordered_uniq_comments, :through => :posts, :source => :comments, :uniq => true, :order => 'comments.id'
28
+ has_many :ordered_uniq_comments_desc, :through => :posts, :source => :comments, :uniq => true, :order => 'comments.id DESC'
29
+ has_many :readonly_comments, :through => :posts, :source => :comments, :readonly => true
30
+
31
+ has_many :special_posts
32
+ has_many :special_post_comments, :through => :special_posts, :source => :comments
33
+
34
+ has_many :special_nonexistant_posts, :class_name => "SpecialPost", :conditions => "posts.body = 'nonexistant'"
35
+ has_many :special_nonexistant_post_comments, :through => :special_nonexistant_posts, :source => :comments, :conditions => "comments.post_id = 0"
36
+ has_many :nonexistant_comments, :through => :posts
37
+
38
+ has_many :hello_posts, :class_name => "Post", :conditions => "posts.body = 'hello'"
39
+ has_many :hello_post_comments, :through => :hello_posts, :source => :comments
40
+ has_many :posts_with_no_comments, :class_name => 'Post', :conditions => 'comments.id is null', :include => :comments
41
+
42
+ has_many :hello_posts_with_hash_conditions, :class_name => "Post",
43
+ :conditions => {:body => 'hello'}
44
+ has_many :hello_post_comments_with_hash_conditions, :through =>
45
+ :hello_posts_with_hash_conditions, :source => :comments
46
+
47
+ has_many :other_posts, :class_name => "Post"
48
+ has_many :posts_with_callbacks, :class_name => "Post", :before_add => :log_before_adding,
49
+ :after_add => :log_after_adding,
50
+ :before_remove => :log_before_removing,
51
+ :after_remove => :log_after_removing
52
+ has_many :posts_with_proc_callbacks, :class_name => "Post",
53
+ :before_add => Proc.new {|o, r| o.post_log << "before_adding#{r.id || '<new>'}"},
54
+ :after_add => Proc.new {|o, r| o.post_log << "after_adding#{r.id || '<new>'}"},
55
+ :before_remove => Proc.new {|o, r| o.post_log << "before_removing#{r.id}"},
56
+ :after_remove => Proc.new {|o, r| o.post_log << "after_removing#{r.id}"}
57
+ has_many :posts_with_multiple_callbacks, :class_name => "Post",
58
+ :before_add => [:log_before_adding, Proc.new {|o, r| o.post_log << "before_adding_proc#{r.id || '<new>'}"}],
59
+ :after_add => [:log_after_adding, Proc.new {|o, r| o.post_log << "after_adding_proc#{r.id || '<new>'}"}]
60
+ has_many :unchangable_posts, :class_name => "Post", :before_add => :raise_exception, :after_add => :log_after_adding
61
+
62
+ has_many :categorizations
63
+ has_many :categories, :through => :categorizations
64
+
65
+ has_many :categories_like_general, :through => :categorizations, :source => :category, :class_name => 'Category', :conditions => { :name => 'General' }
66
+
67
+ has_many :categorized_posts, :through => :categorizations, :source => :post
68
+ has_many :unique_categorized_posts, :through => :categorizations, :source => :post, :uniq => true
69
+
70
+ has_many :nothings, :through => :kateggorisatons, :class_name => 'Category'
71
+
72
+ has_many :author_favorites
73
+ has_many :favorite_authors, :through => :author_favorites, :order => 'name'
74
+
75
+ has_many :tagging, :through => :posts # through polymorphic has_one
76
+ has_many :taggings, :through => :posts, :source => :taggings # through polymorphic has_many
77
+ has_many :tags, :through => :posts # through has_many :through
78
+ has_many :post_categories, :through => :posts, :source => :categories
79
+
80
+ belongs_to :author_address, :dependent => :destroy
81
+ belongs_to :author_address_extra, :dependent => :delete, :class_name => "AuthorAddress"
82
+
83
+ attr_accessor :post_log
84
+
85
+ def after_initialize
86
+ @post_log = []
87
+ end
88
+
89
+ def label
90
+ "#{id}-#{name}"
91
+ end
92
+
93
+ private
94
+ def log_before_adding(object)
95
+ @post_log << "before_adding#{object.id || '<new>'}"
96
+ end
97
+
98
+ def log_after_adding(object)
99
+ @post_log << "after_adding#{object.id}"
100
+ end
101
+
102
+ def log_before_removing(object)
103
+ @post_log << "before_removing#{object.id}"
104
+ end
105
+
106
+ def log_after_removing(object)
107
+ @post_log << "after_removing#{object.id}"
108
+ end
109
+
110
+ def raise_exception(object)
111
+ raise Exception.new("You can't add a post")
112
+ end
113
+ end
114
+
115
+ class AuthorAddress < ActiveRecord::Base
116
+ has_one :author
117
+
118
+ def self.destroyed_author_address_ids
119
+ @destroyed_author_address_ids ||= Hash.new { |h,k| h[k] = [] }
120
+ end
121
+
122
+ before_destroy do |author_address|
123
+ if author_address.author
124
+ AuthorAddress.destroyed_author_address_ids[author_address.author.id] << author_address.id
125
+ end
126
+ true
127
+ end
128
+ end
129
+
130
+ class AuthorFavorite < ActiveRecord::Base
131
+ belongs_to :author
132
+ belongs_to :favorite_author, :class_name => "Author"
133
+ end
@@ -0,0 +1,4 @@
1
+ class AutoId < ActiveRecord::Base
2
+ def self.table_name () "auto_id_tests" end
3
+ def self.primary_key () "auto_id" end
4
+ end
@@ -0,0 +1,2 @@
1
+ class Binary < ActiveRecord::Base
2
+ end
@@ -0,0 +1,4 @@
1
+ class Book < ActiveRecord::Base
2
+ has_many :citations, :foreign_key => 'book1_id'
3
+ has_many :references, :through => :citations, :source => :reference_of, :uniq => true
4
+ end
@@ -0,0 +1,5 @@
1
+ class Categorization < ActiveRecord::Base
2
+ belongs_to :post
3
+ belongs_to :category
4
+ belongs_to :author
5
+ end
@@ -0,0 +1,29 @@
1
+ class Category < ActiveRecord::Base
2
+ has_and_belongs_to_many :posts
3
+ has_and_belongs_to_many :special_posts, :class_name => "Post"
4
+ has_and_belongs_to_many :other_posts, :class_name => "Post"
5
+
6
+ has_and_belongs_to_many(:select_testing_posts,
7
+ :class_name => 'Post',
8
+ :foreign_key => 'category_id',
9
+ :association_foreign_key => 'post_id',
10
+ :select => 'posts.*, 1 as correctness_marker')
11
+
12
+ has_and_belongs_to_many :post_with_conditions,
13
+ :class_name => 'Post',
14
+ :conditions => { :title => 'Yet Another Testing Title' }
15
+ def self.what_are_you
16
+ 'a category...'
17
+ end
18
+
19
+ has_many :categorizations
20
+ has_many :authors, :through => :categorizations, :select => 'authors.*, categorizations.post_id'
21
+ end
22
+
23
+ class SpecialCategory < Category
24
+
25
+ def self.what_are_you
26
+ 'a special category...'
27
+ end
28
+
29
+ end
@@ -0,0 +1,6 @@
1
+ class Citation < ActiveRecord::Base
2
+ belongs_to :reference_of, :class_name => "Book", :foreign_key => :book2_id
3
+
4
+ belongs_to :book1, :class_name => "Book", :foreign_key => :book1_id
5
+ belongs_to :book2, :class_name => "Book", :foreign_key => :book2_id
6
+ end
@@ -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
@@ -0,0 +1,3 @@
1
+ class ColumnName < ActiveRecord::Base
2
+ def self.table_name () "colnametests" end
3
+ end
@@ -0,0 +1,25 @@
1
+ class Comment < ActiveRecord::Base
2
+ named_scope :containing_the_letter_e, :conditions => "comments.body LIKE '%e%'"
3
+
4
+ belongs_to :post, :counter_cache => true
5
+
6
+ def self.what_are_you
7
+ 'a comment...'
8
+ end
9
+
10
+ def self.search_by_type(q)
11
+ self.find(:all, :conditions => ["#{QUOTED_TYPE} = ?", q])
12
+ end
13
+ end
14
+
15
+ class SpecialComment < Comment
16
+ def self.what_are_you
17
+ 'a special comment...'
18
+ end
19
+ end
20
+
21
+ class VerySpecialComment < Comment
22
+ def self.what_are_you
23
+ 'a very special comment...'
24
+ end
25
+ end
@@ -0,0 +1,123 @@
1
+ class AbstractCompany < ActiveRecord::Base
2
+ self.abstract_class = true
3
+ end
4
+
5
+ class Company < AbstractCompany
6
+ attr_protected :rating
7
+ set_sequence_name :companies_nonstd_seq
8
+
9
+ validates_presence_of :name
10
+
11
+ has_one :dummy_account, :foreign_key => "firm_id", :class_name => "Account"
12
+
13
+ def arbitrary_method
14
+ "I am Jack's profound disappointment"
15
+ end
16
+ end
17
+
18
+ module Namespaced
19
+ class Company < ::Company
20
+ end
21
+ end
22
+
23
+ class Firm < Company
24
+ has_many :clients, :order => "id", :dependent => :destroy, :counter_sql =>
25
+ "SELECT COUNT(*) FROM companies WHERE firm_id = 1 " +
26
+ "AND (#{QUOTED_TYPE} = 'Client' OR #{QUOTED_TYPE} = 'SpecialClient' OR #{QUOTED_TYPE} = 'VerySpecialClient' )"
27
+ has_many :clients_sorted_desc, :class_name => "Client", :order => "id DESC"
28
+ has_many :clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id"
29
+ has_many :dependent_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :dependent => :destroy
30
+ has_many :exclusively_dependent_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :dependent => :delete_all
31
+ has_many :limited_clients, :class_name => "Client", :order => "id", :limit => 1
32
+ has_many :clients_like_ms, :conditions => "name = 'Microsoft'", :class_name => "Client", :order => "id"
33
+ has_many :clients_with_interpolated_conditions, :class_name => "Client", :conditions => 'rating > #{rating}'
34
+ has_many :clients_like_ms_with_hash_conditions, :conditions => { :name => 'Microsoft' }, :class_name => "Client", :order => "id"
35
+ has_many :clients_using_sql, :class_name => "Client", :finder_sql => 'SELECT * FROM companies WHERE client_of = #{id}'
36
+ has_many :clients_using_counter_sql, :class_name => "Client",
37
+ :finder_sql => 'SELECT * FROM companies WHERE client_of = #{id}',
38
+ :counter_sql => 'SELECT COUNT(*) FROM companies WHERE client_of = #{id}'
39
+ has_many :clients_using_zero_counter_sql, :class_name => "Client",
40
+ :finder_sql => 'SELECT * FROM companies WHERE client_of = #{id}',
41
+ :counter_sql => 'SELECT 0 FROM companies WHERE client_of = #{id}'
42
+ has_many :no_clients_using_counter_sql, :class_name => "Client",
43
+ :finder_sql => 'SELECT * FROM companies WHERE client_of = 1000',
44
+ :counter_sql => 'SELECT COUNT(*) FROM companies WHERE client_of = 1000'
45
+ has_many :clients_using_finder_sql, :class_name => "Client", :finder_sql => 'SELECT * FROM companies WHERE 1=1'
46
+ has_many :plain_clients, :class_name => 'Client'
47
+ has_many :readonly_clients, :class_name => 'Client', :readonly => true
48
+
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
52
+ end
53
+
54
+ class DependentFirm < Company
55
+ has_one :account, :foreign_key => "firm_id", :dependent => :nullify
56
+ has_many :companies, :foreign_key => 'client_of', :order => "id", :dependent => :nullify
57
+ end
58
+
59
+ class ExclusivelyDependentFirm < Company
60
+ has_one :account, :foreign_key => "firm_id", :dependent => :delete
61
+ has_many :dependent_sanitized_conditional_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :dependent => :delete_all, :conditions => "name = 'BigShot Inc.'"
62
+ has_many :dependent_conditional_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :dependent => :delete_all, :conditions => ["name = ?", 'BigShot Inc.']
63
+ end
64
+
65
+ class Client < Company
66
+ belongs_to :firm, :foreign_key => "client_of"
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"
69
+ belongs_to :firm_with_other_name, :class_name => "Firm", :foreign_key => "client_of"
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
72
+
73
+ # Record destruction so we can test whether firm.clients.clear has
74
+ # is calling client.destroy, deleting from the database, or setting
75
+ # foreign keys to NULL.
76
+ def self.destroyed_client_ids
77
+ @destroyed_client_ids ||= Hash.new { |h,k| h[k] = [] }
78
+ end
79
+
80
+ before_destroy do |client|
81
+ if client.firm
82
+ Client.destroyed_client_ids[client.firm.id] << client.id
83
+ end
84
+ true
85
+ end
86
+
87
+ # Used to test that read and question methods are not generated for these attributes
88
+ def ruby_type
89
+ read_attribute :ruby_type
90
+ end
91
+
92
+ def rating?
93
+ query_attribute :rating
94
+ end
95
+ end
96
+
97
+
98
+ class SpecialClient < Client
99
+ end
100
+
101
+ class VerySpecialClient < SpecialClient
102
+ end
103
+
104
+ class Account < ActiveRecord::Base
105
+ belongs_to :firm
106
+
107
+ def self.destroyed_account_ids
108
+ @destroyed_account_ids ||= Hash.new { |h,k| h[k] = [] }
109
+ end
110
+
111
+ before_destroy do |account|
112
+ if account.firm
113
+ Account.destroyed_account_ids[account.firm.id] << account.id
114
+ end
115
+ true
116
+ end
117
+
118
+
119
+ protected
120
+ def validate
121
+ errors.add_on_empty "credit_limit"
122
+ end
123
+ end
@@ -0,0 +1,61 @@
1
+ module MyApplication
2
+ module Business
3
+ class Company < ActiveRecord::Base
4
+ attr_protected :rating
5
+ end
6
+
7
+ class Firm < Company
8
+ has_many :clients, :order => "id", :dependent => :destroy
9
+ has_many :clients_sorted_desc, :class_name => "Client", :order => "id DESC"
10
+ has_many :clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id"
11
+ has_many :clients_like_ms, :conditions => "name = 'Microsoft'", :class_name => "Client", :order => "id"
12
+ has_many :clients_using_sql, :class_name => "Client", :finder_sql => 'SELECT * FROM companies WHERE client_of = #{id}'
13
+
14
+ has_one :account, :dependent => :destroy
15
+ end
16
+
17
+ class Client < Company
18
+ belongs_to :firm, :foreign_key => "client_of"
19
+ belongs_to :firm_with_other_name, :class_name => "Firm", :foreign_key => "client_of"
20
+
21
+ class Contact < ActiveRecord::Base; end
22
+ end
23
+
24
+ class Developer < ActiveRecord::Base
25
+ has_and_belongs_to_many :projects
26
+ validates_length_of :name, :within => (3..20)
27
+ end
28
+
29
+ class Project < ActiveRecord::Base
30
+ has_and_belongs_to_many :developers
31
+ end
32
+
33
+ end
34
+
35
+ module Billing
36
+ class Firm < ActiveRecord::Base
37
+ self.table_name = 'companies'
38
+ end
39
+
40
+ module Nested
41
+ class Firm < ActiveRecord::Base
42
+ self.table_name = 'companies'
43
+ end
44
+ end
45
+
46
+ class Account < ActiveRecord::Base
47
+ with_options(:foreign_key => :firm_id) do |i|
48
+ i.belongs_to :firm, :class_name => 'MyApplication::Business::Firm'
49
+ i.belongs_to :qualified_billing_firm, :class_name => 'MyApplication::Billing::Firm'
50
+ i.belongs_to :unqualified_billing_firm, :class_name => 'Firm'
51
+ i.belongs_to :nested_qualified_billing_firm, :class_name => 'MyApplication::Billing::Nested::Firm'
52
+ i.belongs_to :nested_unqualified_billing_firm, :class_name => 'Nested::Firm'
53
+ end
54
+
55
+ protected
56
+ def validate
57
+ errors.add_on_empty "credit_limit"
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,4 @@
1
+ class Computer < ActiveRecord::Base
2
+ enable_memcache_querycache
3
+ belongs_to :developer, :foreign_key => 'developer'
4
+ end