Почему обратный вызов before_update с использованием обновленных параметров? Не следует ли использовать исходные параметры?Обратный вызов Before_update вызывается с использованием обновленных атрибутов
У меня есть Round
модель, которая belongs_to
в Case
модели (Case
has_many
Rounds
)
Некоторые из атрибутов Case
вычисляются через обратные вызовы Round
«s. Например, когда есть новый Round
, который был выигрышем, атрибут wins Case
увеличивается на 1.
У меня возникла проблема с обратными вызовами теперь, когда мне нужно обновить свой случай. У меня есть метод add_round
и delete_round
в модели Round
, которые добавляют и удаляют атрибуты заданного раунда соответственно.
Чтобы уточнить, delete_round и add_round фактически не удалить или создать круглую, они удалить или добавить статы раунда к случаям атрибуты
Вот моя круглая модель:
class Round < ActiveRecord::Base
belongs_to :case
after_save :add_round
before_update :delete_round
before_destroy :delete_round
private
# Adds this Round's stats to its Case
def add_round
self.case.add_round(self)
end
# Deletes this Round's stats from its Case
def delete_round
self.case.delete_round(self)
end
end
а вот случай модель:
class Case < ActiveRecord::Base
has_many :rounds, dependent: :destroy
def add_round(round)
if round.win?
update_attribute(wins: wins + 1)
else
update_attribute(losses: losses + 1)
end
update_attribute(win_percentage: 100 * wins/(wins + losses)
end
def delete_round(round)
if round.win?
update_attribute(wins: wins - 1)
else
update_attribute(losses: losses - 1)
end
update_attribute(win_percentage: 100 * wins/(wins + losses)
end
end
и схема:
create_table "cases", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "wins", default: 0
t.integer "losses", default: 0
t.float "win_percentage", default: 0.0
end
create_table "rounds", force: :cascade do |t|
t.integer "case_id"
t.boolean "win"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
Вот грубый псевдокод иш пример того, что я хочу, чтобы это произошло:
case = Case.create(wins: 0, losses: 0, win_percentage: 0)
round = Round.create(win: true, case_id: case.id)
# add_round is called
case.wins = 1
case.losses = 0
case.win_percentage = 100
round.update_attribute(win: false)
# before that parameter is updated, delete_round is called on the round with the old attributes
case.wins = 0
case.losses = 0
case.win_percentage = 0
# after that parameter is updated, add_round is called on the updated round
case.wins = 0
case.losses = 1
case.win_percentage = 0
round.destroy
# delete_round is called
case.wins = 0
case.losses = 0
case.win_percentage = 0
После того, как они обновляются, добавьте раунд с новыми параметрами
По какой-то причине, before_update получает отправленные обновленные атрибуты. Почему это происходит? Как мне изменить обратные вызовы?
Я не мог понять, что вы хотите удалить раунд, когда дело обновляется? или есть еще вещи? – juanpastas
или удалить раунд, когда раунд обновлен ??? – juanpastas
Я хочу удалить старую версию раунда из статистики дел, а затем добавить новую версию. Другими словами, обновление раунда от выигрыша до потери - это то же самое, что и удаление этой победы, а затем добавление убытка. Должно быть яснее: delete_round и add_round не удаляют фактические раунды, они удаляют статистику этого раунда из футляра –