更新关联时如何销毁其他 has_one 关系?
我有一个 User
,它 has_one Widget
。
class User
has_one :widget, :dependent => :destroy
end
class Widget
belongs_to :user
end
当我为 User
创建一个新的 Widget
时,我想销毁与 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
结束
不保留两份副本?
我不想搞砸我的控制器有类似的交易
Widget.transaction do
old_widget.destroy
new_widget.save
end
,但到目前为止,这似乎是唯一的方法。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
看起来您有两个使用路径,用户可以在其中创建小部件。从用户端和小部件端。如果您通过一段代码将它们集中起来,并进行一些唯一性验证以确保不会出现任何失误,那就更好了。
在 user.create_widget 中使用 find_or_create_by 怎么样,以便您可以在需要更新现有小部件或创建新小部件时对其进行编辑。
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.
您应该更新
用户
现有的widget
记录,而不是创建新记录并销毁旧记录。你可以这样做:
You should update the existing
widget
record for theuser
instead of creating a new one and destroying the old one.You can do something like this: