How can I destroy another has_one relation when updating an association?

I have Userone that has_one Widget.

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

class Widget
  belongs_to :user
end

And when I create a new one Widgetfor User, I want to destroy the old one associated with User.

Here is my situation:

Create user:

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

Create a custom widget:

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

Reboot and check the widget:

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

Create a widget, note that the existing widget will be destroyed before saving another:

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

Restore user widget:

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

Create another widget:

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

Now both exist:

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

And the user first:

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

Is there any way to do this:

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

without removing the old widget before saving, or this:

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

without saving two copies?

I do not want to run my transaction controllers like

Widget.transaction do
  old_widget.destroy
  new_widget.save
end

but for now this seems like the only way.

+5
1

, , . . , , .

find_or_create_by user.create_widget, , .

0

All Articles