Как уничтожить другое отношение has_one при обновлении ассоциации? - PullRequest
5 голосов
/ 30 августа 2011

У меня есть User, который имеет_one Widget.

class User
  has_one :widget, :dependent => :destroy
end

class Widget
  belongs_to :user
end

И когда я создаю новый Widget для User, я хочу уничтожить старый, связанный с User.

Вот моя ситуация:

Создать пользователя:

user = User.new
user.save
user # => #<User id: 1>

Создать виджет пользователя:

widget = Widget.new
widget.user = user
widget.save

Перезагрузите и проверьте виджет:

user.reload
user.widget # => #<Widget id: 1, user_id: 1>

Создайте виджет, обратите внимание, что существующий виджет уничтожен до сохранения другого:

user.build_widget # => #<Widget id: nil, user_id: 1>
user.reload
user.widget # => nil

Воссоздание виджета пользователя:

user.create_widget # => #<Widget id: 2, user_id: 1>

Создание другого виджета:

widget = Widget.new :user => user
widget.save

Сейчас,оба существуют:

Widget.find(2) # => #<Widget id: 2, user_id: 1>
Widget.find(3) # => #<Widget id: 3, user_id: 1>

И пользователь первый:

user.reload
user.widget # => #<Widget id: 2, user_id: 1>

Есть ли способ сделать это:

def create
  @widget = current_user.build_widget(params[:widget])

  respond_to do |format|
    if @widget.save
      format.html { redirect_to widget_path, notice: 'Widget was successfully created.' }
      format.json { render json: @widget, status: :created, location: @widget }
    else
      format.html { render action: 'new' }
      format.json { render json: @widget.errors, status: :unprocessable_entity }
    end
  end
end

без удаления старого виджета перед сохранением, или это:

def create
  @widget = Widget.new(params[:widget])
  @widget.user = current_user

  respond_to do |format|
    if @widget.save
      format.html { redirect_to widget_path, notice: 'Widget was successfully created.' }
      format.json { render json: @widget, status: :created, location: @widget }
   else
      format.html { render action: 'new' }
      format.json { render json: @widget.errors, status: :unprocessable_entity }
    end
  end

end

без хранения двух копий?

Я не хочу портить мои контроллеры транзакциями, подобными

Widget.transaction do
  old_widget.destroy
  new_widget.save
end

, но пока, похоже, это единственный путь.

1 Ответ

0 голосов
/ 01 сентября 2011

Похоже, у вас есть два пути использования, где пользователь может создавать виджеты. Со стороны пользователя и со стороны виджета. Было бы лучше, если бы вы направили их через один фрагмент кода и добавили несколько проверок уникальности, чтобы убедиться в отсутствии ошибок.

как насчет find_or_create_by в user.create_widget, чтобы вы могли редактировать существующий виджет, если он нуждается в обновлении, или вы создаете новый.

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