У меня есть 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
, но пока, похоже, это единственный путь.