Rails update_column из seed.rb
У меня есть начальный файл, который генерирует многочисленные объекты, в том числе счета и транзакции по счетам. После создания учетных записей цикл генерирует 80 транзакций для каждой учетной записи (имеется 150 учетных записей).
Все работает хорошо, за исключением того, что мне нужно обновить столбец баланса аккаунта, чтобы отразить изменения, вызванные транзакцией. Я пробовал это 100 разными способами. Вот мой самый последний подход:
от seed.rb
accounts.each do |account|
80.times do
type = types.sample
case (type)
when 1
description = descriptions_ATM_Withdrawal.sample
amount = (atm_amounts.sample) *-1
when 2
description = descriptions_Check.sample
amount = ((500.0 - 5.0) * rand() + 5) *-1
when 3
description = descriptions_Deposit.sample
amount = (2000.0 - 5.0) * rand() + 5
when 4
description = descriptions_AutoDraft.sample
amount = ((350.0 - 5.0) * rand() + 5) *-1
when 5
description = descriptions_POS.sample
amount = ((150.0 - 5.0) * rand() + 5) *-1
when 6
description = descriptions_Transfer
amount = (500.0 - 5.0) * rand() + 5
when 7
description = descriptions_Withdrawal
amount = ((500.0 - 5.0) * rand() + 5) *-1
when 99
description = descriptions_Miscellaneous
amount = ((500.0 - 5.0) * rand() + 5) *-1
end
AcctTransaction.create do |transaction|
transaction.id = SecureRandom.random_number(99999999999999)
transaction.account_id = account.id
transaction.transaction_type_id = type
transaction.description = description
transaction.amount = amount
transaction.adjusted_bal = account.balance + transaction.amount
# keep transaction in chronological order unless it's the first one
unless AcctTransaction.exists?(account_id: transaction.account_id)
transaction.date = rand(account.date_opened..Time.now)
else
transaction.date = rand(AcctTransaction.where(account_id: transaction.account_id).last.date..Time.now)
end
end
Account.find(AcctTransaction.last.account_id).update_column(:balance, AcctTransaction.last.adjusted_bal)
end
end
Попытка обновления с последней строки до "заканчивается". Я пробовал update, update_attribute, а также просто "=". Ничто не похоже на работу. Поле "остаток" счета ДОЛЖНО обновляться после каждой транзакции, чтобы обеспечить точную основу для расчета на следующей итерации цикла создания транзакции счета.
Любые предложения будут рассмотрены. Это не может быть так сложно. Опять же, все это будет работать очень хорошо, если баланс будет обновляться, как и должно.
Rails 4.1.8 / Ruby 2.1.5
Пожалуйста, помогите.. СПАСИБО!
РЕДАКТИРОВАТЬ account.rb:
class Account < ActiveRecord::Base
belongs_to :customer
belongs_to :user
has_one :acct_type
has_many :acct_transactions, :dependent => :destroy
accepts_nested_attributes_for :acct_type
accepts_nested_attributes_for :acct_transactions
validates :acct_type_id, presence: true
end
acct_transaction.rb
class AcctTransaction < ActiveRecord::Base
belongs_to :account
has_one :transaction_type
accepts_nested_attributes_for :transaction_type, :allow_destroy => false
end
снимок экрана (неправильных) результатов
Как вы можете видеть, то, что происходит, является исходным балансом (видимым в заголовке при увеличении), сохраняется. Поэтому каждая транзакция рассчитывается на основе этой суммы.
методы в acct_transactions_controller, которые фактически работают для выполнения этих обновлений, когда приложение работает. Попытка повторить эту функциональность при создании вложенных семян:
public
def modify_acct_balance
account = Account.find(@acct_transaction.account_id)
case @acct_transaction.transaction_type_id
when 1,2,4,5,7
account.update(balance: account.balance - @acct_transaction.amount)
when 3
account.update(balance: account.balance + @acct_transaction.amount)
end
end
def adjust_balance
case @acct_transaction.transaction_type_id
when 2,4,5,7
@acct_transaction.adjusted_bal = Account.find(@acct_transaction.account_id).balance - @acct_transaction.amount
when 3
@acct_transaction.adjusted_bal = Account.find(@acct_transaction.account_id).balance + @acct_transaction.amount
end
end
Обратите внимание, что вышеуказанные методы рассчитываются по-разному в зависимости от типа транзакции (+ или -) - пользователь всегда предоставляет положительное значение. Работает хоть.
Как воспроизвести такую функциональность в вышеуказанном начальном файле?
Спасибо
2 ответа
Чтобы сделать эту работу, мне пришлось сделать 2 вещи:
- Измените синтаксис метода обновления (последняя строка seed.rb) следующим образом:
account.update(balance: transaction.adjusted_bal)
- Добавить! (взрыв) к методу создания (
AcctTransaction.create! do |transaction|
)
Метод create, вероятно, прекрасно работает без взрыва, но я оставляю его, потому что теперь все работает отлично. Кроме того, я не уверен, почему использование обновления работает только с этим синтаксисом. Я пробовал другие варианты и другие методы, чтобы обновить этот столбец, но ни один из них не работал. Почти кажется, что seed.rb работает только с "голыми" методами Rails. Спасибо Deeno и всем остальным, кто помог мне с этим разобраться.
Конечно, есть много способов сделать это, но на первый взгляд кажется, что ваш подход сработает. Сначала я подумал, что у вас есть некоторые ловушки жизненного цикла или конфигурация встречного кэша на моделях, которые противоречат вашей логике. (Вы можете показать нам свои определения модели)
Если это не так, я бы просто пропустил обновление баланса после каждой транзакции и вычислял баланс в конце цикла создания транзакции.
В псевдо:
accounts.each do |account|
80.times do
# create transactions
end
account.reload
account.balance = account.transactions.sum(:adjusted_bal)
account.save
end
Или даже быстрее, создайте и кэшируйте баланс локально во время создания транзакции:
accounts.each do |account|
balance = 0
80.times do
# create transaction
balance += transaction.amount
end
account.balance = balance
account.save
end