No block given(yield) rails 条件验证错误

No block given(yield) rails error on conditional validation

我有一个名为 Transaction 的嵌套表单,其中包含一个名为 Banking Information Form 的子对象。当父级的(交易)transaction_mechanism 字段设置为 "cheque" 时,不应触发银行信息验证。出于某种原因,当我在表单中将 transaction_mechanism 设置为 "cheque" 时,它仍在调用银行信息表单验证。在 bank_information_form 模型中,我有一个名为 cheque_transaction 的方法?如果 transaction_mechanism 是 "cheque",应该可以防止验证触发,但我收到一个错误。

错误

no block given (yield)

transaction.rb

class Transaction < ActiveRecord::Base
  # Require packages
  require 'time'

  # Associations
  belongs_to :user
  has_one :banking_information_form

  # Nested attributes
  accepts_nested_attributes_for :banking_information_form

  # Validations
  validates_associated :banking_information_form
  validate  :check_debit_or_credit
  validates :transaction_mechanism, :transaction_kind, :debit, :salesforce_id, presence: true
  validate  :debit, :credit,numericality: { only_integer: true }
end

banking_information_form.rb

class BankingInformationForm < ActiveRecord::Base
  # Associations
  # Belongs to :transaction
  belongs_to :owner, foreign_key: "transaction_id", class_name: "Transaction"

  # Validations
  validates :financial_institution, :transit_number, :bank_account_number, presence: true, :unless =>    :cheque_transaction?
  validates :transit_number, length: {is: 5,
                                  too_short: "Your transit number is 5 digits long.",
                                  too_long: "Your transit number is 5 digits long."}
  validates :bank_account_number, length: {minimum: 4, maximum: 12,
                                  too_short: "Your bank account number will be between 4 and 12 digits long.",
                                  too_long: "Your bank account number will be between 4 and 12 digits long."}

  private

    def cheque_transaction?
      self.transaction.transaction_mechanism == "Cheque"
    end

结束

class Transaction < ActiveRecord::Base
  has_one :banking_information_form
  # Other code 
end

如您所述,只有当父(交易)机制不是 'Cheque' 时,您的银行信息才会被验证:

class BankingInformationForm < ActiveRecord::Base
  belongs_to :transaction #this was missing in your code.

  validates :financial_institution, :transit_number, 
    :bank_account_number, presence: true, unless: :cheque_transaction?
  # other validations here 

  private 
   def cheque_transaction?
     transaction.transaction_mechanism == "Cheque"
   end
end

经过更多的尝试和错误后,我找到了一种让条件验证起作用的方法。我首先将模型名称从 'Transaction' 更改为 'AccountTransaction'。在发现 'Transaction' 是 rails 中的保留字后,我这样做是为了遵守 rails 的约定。

更改模型名称后,我将我的关联附加到 inverse_of: :account_transaction。更多内容可以阅读 inverse_of here.

account_transaction.rb

class AccountTransaction < ActiveRecord::Base
  # Require packages
  require 'time'

  # Associations
  belongs_to :user
  has_one :banking_information_form, inverse_of: :account_transaction

  # Nested attributes
  accepts_nested_attributes_for :banking_information_form

  # Validations
  validates_associated :banking_information_form
  validate  :check_debit_or_credit
  validates :transaction_mechanism, :transaction_kind, :debit, :salesforce_id, presence: true
  validate  :debit, :credit,numericality: { only_integer: true }
end

banking_information_form.rb

class BankingInformationForm < ActiveRecord::Base
  # Associations
  belongs_to :account_transaction

  # Validations
  validates :financial_institution, :transit_number, :bank_account_number, presence: true, :unless => :cheque_transaction?
  validates :transit_number, length: {is: 5,
                                  too_short: "Your transit number is 5 digits long.",
                                  too_long: "Your transit number is 5 digits long."}, :unless => :cheque_transaction?
  validates :bank_account_number, length: {minimum: 4, maximum: 12,
                                  too_short: "Your bank account number will be between 4 and 12 digits long.",
                                  too_long: "Your bank account number will be between 4 and 12 digits long."}, :unless => :cheque_transaction?

  private

    def cheque_transaction?
      self.account_transaction.transaction_mechanism == "Cheque"
    end
end