I have a User
which has_one Widget
.
class User
has_one :widget, :dependent => :destroy
end
class Widget
belongs_to :user
end
And when I create a new Widget
for a User
, I want to destroy the old one associated with the User
.
Here's my situation:
Create a user:
user = User.new
user.save
user # => #<User id: 1>
Create user's widget:
widget = Widget.new
widget.user = user
widget.save
Reload and check the widget:
user.reload
user.widget # => #<Widget id: 1, user_id: 1>
Build a widget, notice that the existing widget is destroyed before the other is saved:
user.build_widget # => #<Widget id: nil, user_id: 1>
user.reload
user.widget # => nil
Recreate user's 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 user's is the 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 deleting 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 keeping two copies around?
I don't want to muck up my controllers with transactions like
Widget.transaction do
old_widget.destroy
new_widget.save
end
but so far, this seems like the only way.
It looks like you have two usage paths where a user can create widgets. From the user side and from the widget side. It would be better if you funneled them through one piece of code, and put some uniqueness validations up to insure there are no slip ups.
how about a find_or_create_by in user.create_widget so that you can edit the existing widget if it needs to be updated or you create a new one.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With