2011-12-28 10 views
6

Những gì tôi muốn là, xây dựng này bằng cách nào đó với Rails 3.1: UMLCách xử lý các điều kiện xor, đường ray, khóa ngoài và cơ sở dữ liệu sqlite?

Nếu A đã thiết lập một id cho b_id, nó không phải là có thể thiết lập một id cho c_id. Và chắc chắn ngược lại.

Tôi ước tôi có thể làm ở cấp cơ sở dữ liệu từ di chuyển (kiểm tra ràng buộc?). Điều này bằng cách nào đó có thể? Hoặc có hợp lý hơn để thực hiện điều này trong mô hình có xác thực không?

môi trường của tôi:

  • của Ruby 1.9.3
  • Rails 3.1.3
  • SQLite 3.7.3

Trả lời

2

Bạn có thể thực hiện điều này thông qua các hiệp hội đa hình, altho schema thắng' Nhìn chính xác như những gì bạn có, bạn có thể thực hiện cùng một mục tiêu, có một mục A thuộc về một hoặc là B hoặc C nhưng không bao giờ cho cả hai.

Bạn có thể đọc thêm ở đây: http://guides.rubyonrails.org/association_basics.html#polymorphic-associations

Trong ví dụ đưa vào liên kết đó, APicture của họ, và EmployeeProudct là bạn BC:

(sao chép từ nguồn liên kết ở trên):

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

Cảm ơn bạn đã trả lời của bạn! Kết hợp với câu trả lời của @ Frederick, tôi sẽ nhận được một giải pháp hoàn chỉnh cho các câu hỏi của tôi. – Robin

+1

Tôi đồng ý hơn với câu trả lời của @ mynameiscoffey. Chỉ có một cột cho khóa ngoài trong bảng 'A', do đó chúng ta có' imageable_id' và 'imageable_type' trong bảng A –

0

Tôi chắc chắn sẽ viết xác thực cho việc này - dễ dàng hơn trong việc cung cấp thông báo lỗi tốt cho người dùng từ xác thực. Tôi cũng muốn sao lưu nó với một ràng buộc cơ sở dữ liệu. Có vẻ như ràng buộc kiểm tra thực sự có thể thực hiện công việc.

Rails không có hỗ trợ cho điều này mà tôi có thể tìm thấy, do đó bạn sẽ cần phải tạo bảng với sql thô. Bạn cũng sẽ cần phải thay đổi giản đồ dumper thành :sql vì đường ray sẽ không thể tạo ra một schema.rb mô tả điều này thực sự.

tôi đã viết di cư này

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 

Sau đó, trong đường ray console

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

Vì nó là bạn có thể tạo một hàng với không set x_id cũng không y_id. Bạn có thể thay đổi điều này bằng cách thay đổi chế,

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

dường như làm việc cho tôi

+0

Cảm ơn câu trả lời của bạn! Kết hợp với câu trả lời của @ mynameiscoffey, tôi sẽ nhận được giải pháp hoàn chỉnh cho các câu hỏi của mình. – Robin