2013-02-26 75 views
5

我有以下幾點:Rails的一個一對一的關係

class User < ActiveRecord::Base 
    has_one :car, :class_name => 'Car', :foreign_key => 'user_id' 

class Car < ActiveRecord::Base 
    belongs_to :worker, :class_name => 'User', :foreign_key => 'user_id' 

它基本上是一個用戶和汽車之間的一個一對一的關係。

我想要的是用戶能夠擁有一輛並且只有一輛車。這意味着,如果他創建了一輛分配給他的賽車,他將無法創造第二輛車。

這怎麼辦?

+0

here http://rubyonrailsthrissur.wordpress.com/2012/07/19/one-to-one-relation-in-rails/最實際的解釋 – montells 2014-04-11 19:09:17

回答

2

爲什麼不在用戶嘗試添加汽車之前進行測試?

if worker.car 
raise "sorry buddy, no car for you" 
else 
car = Car.create(user_id: worker.id) 
end 
+0

非常感謝,它的工作原理。 – cgf 2013-02-26 20:46:35

14

當然有一些不同的方法來完成這一點。我建議在該表上創建一個複合鍵索引,以確保user_id在表中是唯一的。這將確保它只會出現一次。在遷移中,你可以寫這樣的東西。

add_index(:cars, :worker_id, :unique => true) 

第一個參數是表名(不要忘記這通常是類名的複數形式)。字段名稱排在第二位。唯一的真實是什麼會阻止你插入額外的行。

注意:這是一個數據庫級約束。如果你點擊這個,因爲驗證沒有捕獲它,它會拋出一個錯誤。

除了此解決方案之外,您還需要向Car模型本身添加驗證。

validates_uniqueness_of :worker_id, message: "can not have more than one car" 

你會看到這個錯誤來通過像「工人ID不能有多個車」。您很可能想要自定義此「工人ID」部分。有關如何操作的說明,請參閱此post

你當然不必做數據庫約束,但如果有其他人插入到數據庫中,這是一個好主意。否則,就Rails而言,您將擁有「無效」數據。