Удалите какую-то запись, а затем откатитесь, если условие не выполняется в рельсах - PullRequest
0 голосов
/ 11 июля 2020

Проблема?

У меня есть приложение Rails5. У меня две модели. Team и Players. Между ними существует ассоциация has_many & belongs_to.

class Team < ApplicationRecord
  has_many :players
end


class Player < ApplicationRecord
  belongs_to :team
end

Теперь я хочу выполнить destroy игроков перед обновлением модели team. Условие выглядит так:

def update
  @team.players.destroy_all if a
  ........
  if b
  .... some code.....
  elsif c
    @team.players.destroy_all
  end
  if @team.update_attributes(team_params)
    redirect_to teams_path
  else
  ... some code..
    render :edit
  end
end

Примечание

В team_params у меня есть players_attributes, поэтому каждый раз, если есть новая запись, мне нужно удалите все старые записи, а затем @team.update_attributes вставит записи в players.

Ожидания

Если @team.update_attributes(team_parmas) не удается, тогда @team.players должно быть откат .

То, что я пробовал

Я попытался добавить Transactions в первую строку метода update, но он не работает .

1 Ответ

1 голос
/ 11 июля 2020

Вы можете использовать драгоценный камень, подобный бумажному следу, для хранения истории, но природа рельсов состоит в том, чтобы не иметь возможности откатывать транзакции после их фиксации. Один из способов имитировать это - сохранить атрибуты во временном наборе хэшей и повторно сохранить их, если вам снова понадобятся записи. У вас может быть logi c like

team_players = @team.players.map(&:attributes)

Затем, если вам нужно «откатиться»

team_players.each do |team_player|
    TeamPlayer.create(team_player)
end

Это будет работать только с базовыми атрибутами c. Если у вас есть другие отношения модели, вам также придется обрабатывать их с помощью атрибутов.

...