6

Hey all, Tôi có một cái gì đó của một yêu cầu thú vị cho dự án của tôi. Tôi cần một mối quan hệ has_one, nơi nó là một trong hai lớp hoặc khác, nhưng không có thừa kế. Tôi có thể lấy đi thừa kế nếu đó là cách duy nhất, nhưng hai bản ghi liên kết có dữ liệu hoàn toàn khác nhau và không liên quan gì cả.RoR: has_one "hoặc khác"? (Hoặc, đa hình mà không có thừa kế.)

Điều tôi cần tìm hiểu là điều gì đó như sau.

# 1. Foo never belongs to anything. 
# 2. Foo MUST have one assigned sub-record for validity. 
# 3. Foo can only have either Bar or Baz assigned. 
# 4. Bar and Baz have only ONE common property, and aren't 
# related in either data or implementation. 

class Foo < ActiveRecord::Base 
    # Attributes: id, name, value 
    has_one :assignment, :foreign_key => 'assigned_to', :readonly => true 
      # Could really use an :object_type for has_one here... 
end 

class Bar < ActiveRecord::Base 
    # Attributes: name,... 
end 

class Baz < ActiveRecord::Base 
    # Attributes: name,... 
end 

đâu Foo có một nhiệm vụ, loại hoặc Bar hoặc Baz; họ chỉ chia sẻ một cột chung, vì vậy có lẽ tôi có thể tạo một đối tượng cha mẹ từ đó. Tuy nhiên, nếu tôi làm cho chúng kế thừa từ một đối tượng chung (khi dữ liệu mà chúng chứa thực sự là cam và táo), tôi có phải tạo một bảng cho bản ghi không? Có lẽ tôi có thể thoát khỏi nó nếu hồ sơ là một hồ sơ trừu tượng, nhưng các em thì không?

Tôi giả sử bây giờ bạn có thể thấy khó khăn của mình. Tôi khá mới đối với RoR nhưng yêu thích nó cho đến nay. Tôi chắc chắn có một cách xung quanh điều này, nhưng tôi sẽ bị xỉn nếu tôi không thể tìm ra nó là gì.

Trả lời

8

Bạn đang cố gắng mô hình hóa thứ gì đó không phù hợp với mô hình cơ sở dữ liệu quan hệ. Tất cả các tham chiếu trong SQL có một nguồn gốc và một đích.

FWIW, Hiệp hội đa hình cũng là một mẫu chống phá vỡ vì nó vi phạm quy tắc này. Nó phải là một đầu mối rằng đó là một thiết kế bị hỏng khi các tài liệu nói rằng bạn phải từ bỏ một ràng buộc toàn vẹn tham chiếu để làm cho nó hoạt động!

Bạn cần Foo có hai mối quan hệ has_one: một đến Bar và một đến Baz. Sau đó, thực hiện một số lớp logic để cố gắng đảm bảo chỉ có một tham chiếu được điền trong bất kỳ trường hợp nào của Foo. Đó là, các tham chiếu đến Bar và Baz, một trong những phải có một giá trị và khác phải được nil, nhưng điều này là một cái gì đó cho mã của bạn để kiểm tra và thực thi.

+0

Điểm tốt, tuy nhiên đôi khi chúng tôi không được tự do hoàn toàn về cách cơ sở dữ liệu được thiết kế hoặc cách dữ liệu có liên quan. Đặc biệt là khi làm việc với một sản phẩm hoặc thư viện được sản xuất bởi người khác. Hai mối quan hệ has_one sẽ hoạt động tốt; Cảm ơn bạn đã hiểu biết của bạn. –

0

Có lẽ một cách để làm điều này, là tạo ra các liên kết có một trong Foo, cho Bar và Baz. Sau đó, tạo một phương thức được gọi là gán và gán = có thể là cách duy nhất để truy cập Bar và Baz. Bạn có thể kiểm tra xem hai has_ones nào không phải là nil trong phương thức get và trả về giá trị đó. Trong phương thức gán, bạn có thể kiểm tra kiểu biến được truyền vào là gì và thiết lập đúng mối quan hệ có một với đối tượng đó và đặt đối số khác thành nil. Điều đó phải bao gồm tất cả các căn cứ của bạn mà không quá phức tạp.

Các vấn đề liên quan