2011-12-28 63 views
6

我要的是,使用Rails 3.1莫名其妙地建設這個: UML如何處理異或條件,rails,外鍵和sqlite數據庫?

如果A樹立了一個ID爲b_id,它不應該是可能的設置ID爲c_id。反之亦然。

我希望我可以在遷移(檢查約束?)的數據庫級別做什麼。這是否有可能? 或者在驗證模型中做到這一點更實惠嗎?

我的環境:

  • 的Ruby 1.9.3
  • 的Rails 3.1.3
  • SQLite的3.7.3

回答

2

您可以通過多態關聯做到這一點,本書雖然架構贏得了」 t看起來完全像你擁有的東西,你可以完成相同的目標,有一個項目A屬於BC但從來沒有。

你可以在這裏閱讀更多:http://guides.rubyonrails.org/association_basics.html#polymorphic-associations

在該鏈路上給出的例子,A是他們PictureEmployeeProudct是你BC

(從源代碼上面鏈接複製):

class Picture < ActiveRecord::Base 
    belongs_to :imageable, :polymorphic => true 
end 

class Employee < ActiveRecord::Base 
    has_many :pictures, :as => :imageable 
end 

class Product < ActiveRecord::Base 
    has_many :pictures, :as => :imageable 
end 
+0

謝謝您的回答工作!結合@弗雷德裏克的回答,我會得到一個完整的解決我的問題。 – Robin 2011-12-31 11:19:11

+1

我會同意@ mynameiscoffey的回答。在表'A'中只有一列用於外鍵,因此我們在表A中有'imageable_id'和'imageable_type' A – 2012-01-03 06:57:18

0

我肯定會爲此編寫驗證 - 提供良好的錯誤消息更容易從驗證到用戶。我還想用數據庫約束來備份它。看起來檢查限制確實可以完成這項工作。

Rails不支持這個,我可以找到,所以你需要創建與原始的SQL表。您還需要將架構傾卸器更改爲:sql,因爲rails將無法生成實際描述這種情況的schema.rb

我在軌控制檯

Foo.create(:x_id => 1, :y_id => 1) #=> SQLite3::ConstraintException 

因爲它是你可以創建一個行既不X_ID也不y_id集寫了這個遷移

class CreateFoos < ActiveRecord::Migration 
    def change 

    execute <<SQL 
     CREATE TABLE foos (
     id INTEGER PRIMARY KEY, 
     x_id INTEGER, 
     y_id INTEGER, 
     constraint xorit check((x_id OR y_id) AND NOT(x_id AND y_id)) 
    ) 
SQL 
    end 
end 

然後。您可以通過改變約束改變這一狀況,

(x_id IS NOT NULL OR y_id IS NOT NULL) AND (x_id IS NULL OR y_id IS NULL) 

似乎爲我

+0

謝謝您的回答!結合@ mynameiscoffey的回答,我會得到一個完整的解決方案來解決我的問題。 – Robin 2011-12-31 11:19:41