2011-08-29 11 views
5

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.

Respuesta

0

Parece que tiene dos rutas de uso donde un usuario puede crear widgets. Del lado del usuario y del lado del widget.Sería mejor si los canalizara a través de una pieza de código y pusiera algunas validaciones de singularidad para asegurar que no haya deslizamientos.

qué tal un find_or_create_by en user.create_widget para que pueda editar el widget existente si necesita ser actualizado o si crea uno nuevo.

Cuestiones relacionadas