Tengo un User
que tiene_una Widget
.¿Cómo destruyo la otra relación has_one al actualizar una asociación?
class User
has_one :widget, :dependent => :destroy
end
class Widget
belongs_to :user
end
Y cuando se crea un nuevo Widget
para un User
, que quieren destruir el viejo asociado a la User
.
Aquí está mi situación:
Crear un usuario:
user = User.new
user.save
user # => #<User id: 1>
Crear widget del usuario:
widget = Widget.new
widget.user = user
widget.save
Actualizar y comprobar el widget:
user.reload
user.widget # => #<Widget id: 1, user_id: 1>
crear un widget, observe que el widget existente es destruido antes que el otro se salva:
user.build_widget # => #<Widget id: nil, user_id: 1>
user.reload
user.widget # => nil
Reproductor de crear cuentas de usuario:
user.create_widget # => #<Widget id: 2, user_id: 1>
Crear otro widget:
widget = Widget.new :user => user
widget.save
Ahora, ambos existen:
Widget.find(2) # => #<Widget id: 2, user_id: 1>
Widget.find(3) # => #<Widget id: 3, user_id: 1>
Y el usuario de es la primera:
user.reload
user.widget # => #<Widget id: 2, user_id: 1>
¿Hay alguna manera de hacer esto:
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
sin eliminar el widget de edad antes de guardar, o esto:
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
final
sin mantener dos copias en todo?
Yo no quiero arruinar definitivamente mis controladores con transacciones como
Widget.transaction do
old_widget.destroy
new_widget.save
end
pero hasta ahora, esto parece la única manera.