Как создать 2 записи с разными идентификаторами? - PullRequest
0 голосов
/ 27 мая 2019

У меня есть проект, в котором люди должны торговать кредитами между ними.

Я делаю это

Модель пользователя

class User < ApplicationRecord
  after_create :create_bank_account

  has_one :bank_account, inverse_of: :user, dependent: :destroy
  has_many :account_transactions, inverse_of: :user, through: :bank_account
end

Модель банка

class BankAccount < ApplicationRecord
  belongs_to :user, inverse_of: :bank_account

  validates :balance, presence: true, numericality: true
  validates :user, presence: true

  has_many :account_transactions, inverse_of: :bank_account, dependent: :destroy
  accepts_nested_attributes_for :account_transactions

  before_validation :load_defaults

  def load_defaults
    if self.new_record?
    self.balance = 4.0
  end
end

Модель транзакций по счету

class AccountTransaction < ApplicationRecord
  after_initialize :set_default_status, if: :new_record?
  after_commit :transfer, on: :create

  belongs_to :bank_account, inverse_of: :account_transactions

  enum transaction_type: [ :Received, :Sent ]
  enum status: [ :Approved, :Canceled ]

  def set_default_status
    self.status ||= :"Approved"
  end

  private

  def transfer
    source_account = BankAccount.find(source)
    target_account = BankAccount.find(target)
    ActiveRecord::Base.transaction do
      source_account.balance -= amount
      target_account.balance += amount
      source_account.save!
      target_account.save!
    end
  end   
end

Кредитный перевод работает нормально.

Но мне нужно создать записи с bank_id каждого пользователя.

Как мне создать эти 2 записи транзакций по счету?

Запись с bank_id пользователя A и другая запись с bank_id пользователя B.

Я не знаю, будет ли лучший способ обрабатывать транзакции между пользователями таким образом

1 Ответ

1 голос
/ 27 мая 2019

Зачем вам нужно 2 записи для AccountTransaction?Я настоятельно рекомендую вам сохранить 2 bank_account идентификатора в модели AccountTransaction, см .:

# acount_transaction.rb
class AccountTransaction < ApplicationRecord
  after_initialize :set_default_status, if: :new_record?
  after_commit :transfer, on: :create

  belongs_to :target_bank_account, foreign_key: 'target_id', class_name: 'BankAccount'
  belongs_to :source_bank_account, foreign_key: 'source_id', class_name: 'BankAccount'

  enum transaction_type: [ :Received, :Sent ]
  enum status: [ :Approved, :Canceled ]

  def set_default_status
    self.status ||= :"Approved"
  end

  private

  def transfer
    ActiveRecord::Base.transaction do
      self.source_bank_account.balance -= amount
      self.target_bank_account.balance += amount
      source_bank_account.save!
      target_bank_account.save!
    end
  end   
end

Вам просто нужно создать новую миграцию, добавив target_id и source_id к AcountTransaction.

Если вы сделаете это, вы сможете сохранить только в 1 записи source_account и target_account, это имеет больше смысла, как вы думаете?

Обновление

Вы должны удалить bank_id и создать 2 новых foreing_keys: target_bank_id и source_bank_id для AccountModel.

В модели BankAccount можно добавить следующие строки:

# bank_account.rb
has_many incoming_transfers, foreign_key: 'target_bank_id', class_name: 'AccountTransaction' 
has_many made_transfers
, foreign_key: 'source_bank_id', class_name: 'AccountTransaction' 

После этого вы можете проверить для каждого BankAccount, сколько переводов сделано и получено!

Вы можете узнать больше об этом виде ассоциации , нажав здесь!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...