rails/activerecord/test/models/account.rb
Tekin Suleyman 5a3e34ed1d
Ensure Contextual validations fire on associations
If a custom validation context is used, the validations on dependent
association records should fire regardless of whether those record have
`changed_for_autosave?` or not as the use of a custom validation context
increases the chance that validations for the context will be different
to those from when the record was first saved.

6ea80b6 changed the autosave behaviour for single associations such that
validations would only fire on an associated record if the record was
`changed_for_autosave?`. This brought the behaviour inline with that for
collection associations, but introduce a regression in that validations
would no longer fire on dependent associations, even when using a custom
validation context.

This change updates the behaviour for both single and collection
associations.

This commit also updates another related regression test that became a
potential false-positive when 6ea80b6 was merged. The original test was
written to protect against non-custom validations firing on associations
(see #14106). At the time validations on autosaving singular
associations would always fire, even when the association was not dirty,
whereas after 6ea80b6 the validations only fire if the association is
dirty. This update to the test makes the association record dirty to
ensure the validations will fire so that the code responsible for
excluding non-custom contexts is correctly exercised.
2019-10-04 12:17:53 +01:00

47 lines
1.2 KiB
Ruby

# frozen_string_literal: true
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.
scope :open, -> { where("firm_name = ?", "37signals") }
scope :available, -> { open }
before_destroy do |account|
if account.firm
Account.destroyed_account_ids[account.firm.id] << account.id
end
end
validate :check_empty_credit_limit
validate :ensure_good_credit, on: :bank_loan
private
def check_empty_credit_limit
errors.add("credit_limit", :blank) if credit_limit.blank?
end
def ensure_good_credit
errors.add(:credit_limit, "too low") unless credit_limit > 10_000
end
def private_method
"Sir, yes sir!"
end
end
class SubAccount < Account
def self.instantiate_instance_of(klass, attributes, column_types = {}, &block)
klass = superclass
super
end
private_class_method :instantiate_instance_of
end