2009-09-26 21 views
9

Tôi hơi bối rối về cách hoạt động này ngay cả khi nó hoạt động đúng cách. Tôi có một mô hình có hai liên kết với cùng một mô hình khác.has_one và has_many trong cùng một kiểu máy. Đường ray theo dõi chúng như thế nào?

Công ty có chủ sở hữu và công ty có nhiều nhân viên của người dùng trong lớp.

đây là mô hình công ty của tôi:

class Company < ActiveRecord::Base 
    validates_presence_of :name 

    has_many :employee, :class_name => 'User' 
    has_one :owner, :class_name => 'User' 
    accepts_nested_attributes_for :owner, :allow_destroy => true 
end 

đây là mô hình người dùng của tôi:

class User < ActiveRecord::Base 
    include Clearance::User 
    attr_accessible :lastname, :firstname #other attr are whitelisted in clearance gem 
    validates_presence_of :lastname, :firstname 
    belongs_to :company 
end 

Bây giờ giả sử tôi có 3 nhân viên của công ty này bao gồm chủ sở hữu. Khi tôi lần đầu tiên tạo công ty, tôi đặt chủ sở hữu cho nhân viên có id 1 và hai người khác (2,3) được thêm vào danh sách nhân viên bằng cách đặt company_id của họ (user.company = company). Cả ba có company_id của họ được đặt thành id công ty mà chúng tôi có thể giả định là 1

khi tôi yêu cầu công ty.chủ sở hữu, tôi nhận đúng người dùng và khi tôi làm company.employee, tôi nhận được cả ba.

Nếu tôi thay đổi chủ sở hữu thành người dùng 2, nó sẽ tự động xóa người dùng 1 khỏi nhân viên bằng cách đặt từ company_id thành 0. Điều này là tốt và nếu tôi thêm anh ta trở lại như một nhân viên đơn giản tất cả vẫn còn tốt.

Làm cách nào mà đường ray biết đường nào? Ý tôi là làm thế nào để biết rằng một nhân viên là chủ sở hữu và không chỉ là một nhân viên? Không có gì trong lược đồ định nghĩa điều này.

Tôi có cảm giác mình nên đảo ngược liên kết của chủ sở hữu và biến công ty thuộc về một người dùng.

Trả lời

12

Như bạn đã có, không có gì để phân biệt chủ sở hữu với nhân viên. Điều này có nghĩa là bạn sẽ gặp sự cố khi bạn bắt đầu xóa mọi người hoặc cố gắng thay đổi quyền sở hữu.

Như François chỉ ra, bạn chỉ may mắn khi chủ sở hữu là người dùng thuộc về công ty có ID thấp nhất.

Để khắc phục sự cố, tôi sẽ có các mô hình của mình có liên quan trong maner sau.

class Company < ActiveRecord::Base 
    belongs_to :owner, :class_name => "user" 
    has_many :employees, :class_name => "user" 
    validates_presence_of :name 
    accepts_nested_attributes_for :owner, :allow_destroy => true 
end 

class User < ActiveRecord::Base 
    include Clearance::User 
    attr_accessible :lastname, :firstname #other attr are whitelisted in clearance gem 
    validates_presence_of :lastname, :firstname 
    belongs_to :company 
    has_one :company, :foreign_key => :owner_id 
end 

Bạn sẽ phải thêm cột khác được gọi là owner_id vào bảng công ty, nhưng điều này rõ ràng xác định mối quan hệ của bạn. Và sẽ tránh mọi rắc rối liên quan đến việc thay đổi chủ sở hữu. Lưu ý rằng có thể có sự phụ thuộc theo chu kỳ nếu bạn đi tuyến đường này và đặt cơ sở dữ liệu của bạn để cả hai người dùng.company_id và companies.owner_id không thể rỗng.

Tôi không hoàn toàn chắc chắn accept_nested_attributes_for sẽ chơi như thế nào với mối quan hệ thuộc_toặc.

+0

Đã kết thúc thực hiện việc này và ở phía người dùng, tôi đã thuộc về: chủ nhân:: class_name => "Company" mà tôi cần làm để ngăn chặn xung đột với user.company, giờ đây user.company là công ty và công ty được sở hữu .employer là ... bạn nhận được điểm: P – nkassis

0

Bạn có thể có một mô hình gọi là quyền sở hữu -

ownership belongs_to company 
ownership belongs_to user 

user has_many ownerships 
company has_one ownership 
5

has_one là cú pháp đường cho:

has_many :whatevers, :limit => 1 

có một thêm chút :limit => 1, do đó đảm bảo chỉ có 1 kỷ lục là bao giờ trả lại. Trong một tuyên bố của bạn, hãy chắc chắn rằng bạn có một mệnh đề :order, để trả lại bản ghi phù hợp trong mọi trường hợp. Trong trường hợp này, tôi sẽ đặt một lá cờ trên nhân viên để biểu thị ai là chủ sở hữu và sắp xếp theo cột này để có được bản ghi đúng thứ nhất.

Câu hỏi của bạn về cách Rails biết điều này là vì hầu hết các cơ sở dữ liệu sẽ trả về các bản ghi theo thứ tự khóa chính của chúng. Vì vậy, nhân viên được thêm 1 có ID 1, do đó sẽ được trả về lần thứ nhất.

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