2011-08-29 49 views
5

我有一個User其中has_one Widget更新關聯時如何銷燬其他has_one關係?

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 

但到目前爲止,這似乎是唯一的出路。

回答

0

看起來您有兩條使用路徑,用戶可以在其中創建小部件。從用戶端和小部件端。這將是更好,如果你通過一段代碼漏斗他們,並把一些獨特的驗證了,以確保有沒有滑動窗口。

怎麼樣在user.create_widget,這樣,如果需要進行更新,或創建一個新的,你可以編輯現有的小部件find_or_create_by。