aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/models/company.rb
blob: c6a5bf1c921a46fe81b0068dd7ced2e7f2662e61 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
class AbstractCompany < ActiveRecord::Base
  self.abstract_class = true
end

class Company < AbstractCompany
  self.sequence_name = :companies_nonstd_seq

  validates_presence_of :name

  has_one :dummy_account, foreign_key: "firm_id", class_name: "Account"
  has_many :contracts
  has_many :developers, through: :contracts

  scope :of_first_firm, lambda {
    joins(account: :firm).
    where("firms.id" => 1)
  }

  def arbitrary_method
    "I am Jack's profound disappointment"
  end

  private

    def private_method
      "I am Jack's innermost fears and aspirations"
    end

    class SpecialCo < Company
    end
end

module Namespaced
  class Company < ::Company
  end

  class Firm < ::Company
    has_many :clients, class_name: "Namespaced::Client"
  end

  class Client < ::Company
  end
end

class Firm < Company
  to_param :name

  has_many :clients, -> { order "id" }, dependent: :destroy, before_remove: :log_before_remove, after_remove: :log_after_remove
  has_many :unsorted_clients, class_name: "Client"
  has_many :unsorted_clients_with_symbol, class_name: :Client
  has_many :clients_sorted_desc, -> { order "id DESC" }, class_name: "Client"
  has_many :clients_of_firm, -> { order "id" }, foreign_key: "client_of", class_name: "Client", inverse_of: :firm
  has_many :clients_ordered_by_name, -> { order "name" }, class_name: "Client"
  has_many :unvalidated_clients_of_firm, foreign_key: "client_of", class_name: "Client", validate: false
  has_many :dependent_clients_of_firm, -> { order "id" }, foreign_key: "client_of", class_name: "Client", dependent: :destroy
  has_many :exclusively_dependent_clients_of_firm, -> { order "id" }, foreign_key: "client_of", class_name: "Client", dependent: :delete_all
  has_many :limited_clients, -> { limit 1 }, class_name: "Client"
  has_many :clients_with_interpolated_conditions, ->(firm) { where "rating > #{firm.rating}" }, class_name: "Client"
  has_many :clients_like_ms, -> { where("name = 'Microsoft'").order("id") }, class_name: "Client"
  has_many :clients_like_ms_with_hash_conditions, -> { where(name: "Microsoft").order("id") }, class_name: "Client"
  has_many :plain_clients, class_name: "Client"
  has_many :clients_using_primary_key, class_name: "Client",
           primary_key: "name", foreign_key: "firm_name"
  has_many :clients_using_primary_key_with_delete_all, class_name: "Client",
           primary_key: "name", foreign_key: "firm_name", dependent: :delete_all
  has_many :clients_grouped_by_firm_id, -> { group("firm_id").select("firm_id") }, class_name: "Client"
  has_many :clients_grouped_by_name, -> { group("name").select("name") }, class_name: "Client"

  has_one :account, foreign_key: "firm_id", dependent: :destroy, validate: true
  has_one :unvalidated_account, foreign_key: "firm_id", class_name: "Account", validate: false
  has_one :account_with_select, -> { select("id, firm_id") }, foreign_key: "firm_id", class_name: "Account"
  has_one :readonly_account, -> { readonly }, foreign_key: "firm_id", class_name: "Account"
  # added order by id as in fixtures there are two accounts for Rails Core
  # Oracle tests were failing because of that as the second fixture was selected
  has_one :account_using_primary_key, -> { order("id") }, primary_key: "firm_id", class_name: "Account"
  has_one :account_using_foreign_and_primary_keys, foreign_key: "firm_name", primary_key: "name", class_name: "Account"
  has_one :account_with_inexistent_foreign_key, class_name: "Account", foreign_key: "inexistent"
  has_one :deletable_account, foreign_key: "firm_id", class_name: "Account", dependent: :delete

  has_one :account_limit_500_with_hash_conditions, -> { where credit_limit: 500 }, foreign_key: "firm_id", class_name: "Account"

  has_one :unautosaved_account, foreign_key: "firm_id", class_name: "Account", autosave: false
  has_many :accounts
  has_many :unautosaved_accounts, foreign_key: "firm_id", class_name: "Account", autosave: false

  has_many :association_with_references, -> { references(:foo) }, class_name: "Client"

  has_one :lead_developer, class_name: "Developer"
  has_many :projects

  def log
    @log ||= []
  end

  private
    def log_before_remove(record)
      log << "before_remove#{record.id}"
    end

    def log_after_remove(record)
      log << "after_remove#{record.id}"
    end
end

class DependentFirm < Company
  has_one :account, foreign_key: "firm_id", dependent: :nullify
  has_many :companies, foreign_key: "client_of", dependent: :nullify
  has_one :company, foreign_key: "client_of", dependent: :nullify
end

class RestrictedWithExceptionFirm < Company
  has_one :account, -> { order("id") }, foreign_key: "firm_id", dependent: :restrict_with_exception
  has_many :companies, -> { order("id") }, foreign_key: "client_of", dependent: :restrict_with_exception
end

class RestrictedWithErrorFirm < Company
  has_one :account, -> { order("id") }, foreign_key: "firm_id", dependent: :restrict_with_error
  has_many :companies, -> { order("id") }, foreign_key: "client_of", dependent: :restrict_with_error
end

class Client < Company
  belongs_to :firm, foreign_key: "client_of"
  belongs_to :firm_with_basic_id, class_name: "Firm", foreign_key: "firm_id"
  belongs_to :firm_with_select, -> { select("id") }, class_name: "Firm", foreign_key: "firm_id"
  belongs_to :firm_with_other_name, class_name: "Firm", foreign_key: "client_of"
  belongs_to :firm_with_condition, -> { where "1 = ?", 1 }, class_name: "Firm", foreign_key: "client_of"
  belongs_to :firm_with_primary_key, class_name: "Firm", primary_key: "name", foreign_key: "firm_name"
  belongs_to :firm_with_primary_key_symbols, class_name: "Firm", primary_key: :name, foreign_key: :firm_name
  belongs_to :readonly_firm, -> { readonly }, class_name: "Firm", foreign_key: "firm_id"
  belongs_to :bob_firm, -> { where name: "Bob" }, class_name: "Firm", foreign_key: "client_of"
  has_many :accounts, through: :firm, source: :accounts
  belongs_to :account

  validate do
    firm
  end

  class RaisedOnSave < RuntimeError; end
  attr_accessor :raise_on_save
  before_save do
    raise RaisedOnSave if raise_on_save
  end

  class RaisedOnDestroy < RuntimeError; end
  attr_accessor :raise_on_destroy
  before_destroy do
    raise RaisedOnDestroy if raise_on_destroy
  end

  # Record destruction so we can test whether firm.clients.clear has
  # is calling client.destroy, deleting from the database, or setting
  # foreign keys to NULL.
  def self.destroyed_client_ids
    @destroyed_client_ids ||= Hash.new { |h, k| h[k] = [] }
  end

  before_destroy do |client|
    if client.firm
      Client.destroyed_client_ids[client.firm.id] << client.id
    end
    true
  end

  before_destroy :overwrite_to_raise

  # Used to test that read and question methods are not generated for these attributes
  def rating?
    query_attribute :rating
  end

  def overwrite_to_raise
  end
end

class ExclusivelyDependentFirm < Company
  has_one :account, foreign_key: "firm_id", dependent: :delete
  has_many :dependent_sanitized_conditional_clients_of_firm, -> { order("id").where("name = 'BigShot Inc.'") }, foreign_key: "client_of", class_name: "Client", dependent: :delete_all
  has_many :dependent_hash_conditional_clients_of_firm, -> { order("id").where(name: "BigShot Inc.") }, foreign_key: "client_of", class_name: "Client", dependent: :delete_all
  has_many :dependent_conditional_clients_of_firm, -> { order("id").where("name = ?", "BigShot Inc.") }, foreign_key: "client_of", class_name: "Client", dependent: :delete_all
end

class SpecialClient < Client
end

class VerySpecialClient < SpecialClient
end

class Account < ActiveRecord::Base
  belongs_to :firm, class_name: "Company"
  belongs_to :unautosaved_firm, foreign_key: "firm_id", class_name: "Firm", autosave: false

  alias_attribute :available_credit, :credit_limit

  def self.destroyed_account_ids
    @destroyed_account_ids ||= Hash.new { |h, k| h[k] = [] }
  end

  # Test private kernel method through collection proxy using has_many.
  def self.open
    where("firm_name = ?", "37signals")
  end

  before_destroy do |account|
    if account.firm
      Account.destroyed_account_ids[account.firm.id] << account.id
    end
    true
  end

  validate :check_empty_credit_limit

  private

    def check_empty_credit_limit
      errors.add("credit_limit", :blank) if credit_limit.blank?
    end

    def private_method
      "Sir, yes sir!"
    end
end