2010-01-24 39 views
7

Tôi có một mô hình, Couple, trong đó có hai cột, first_person_idsecond_person_id và mô hình khác, Person, có khóa chính là person_id và có cột nameActiveRecord has_many nơi hai cột trong bảng A là khóa chính trong bảng B

Đây là cách sử dụng tôi muốn:

#including 'Person' model for eager loading, this is crucial for me 
c = Couple.find(:all, :include => :persons)[0] 
puts "#{c.first_person.name} and #{c.second_person.name}" 

Vậy làm cách nào tôi có thể thực hiện việc này?

+0

Nếu bạn đang sử dụng Rails, tại sao sẽ khóa chính trên mô hình Person là "Person_Id "và không chỉ" id "? – tfwright

+0

Tôi đã thay đổi tên của các mô hình của mình cho bài đăng này vì tôi muốn giữ tên trên internet. Nó phải là 'id' nhưng đó không phải là một sửa chữa khó khăn. Chỉ cần sử dụng 'set_primary_key'. – user94154

Trả lời

13

Các mối quan hệ khai báo trong Couple sẽ trông như thế này:

class Couple 
    named_scope :with_people, { :include => [:first_person, :second_person] } 
    belongs_to :first_person, :class_name => 'Person' 
    belongs_to :second_person, :class_name => 'Person' 
end 

#usage: 
Couple.with_people.first 
# => <Couple ... @first_person: <Person ...>, @second_person: <Person ...>> 

Những người trong Person phụ thuộc vào việc một Person thể là một phần của nhiều hơn một Couple. Nếu một Person chỉ có thể thuộc về một Couple và không thể là "đầu tiên" Person trên một và Second ngày khác, bạn có thể muốn:

class Person 
    has_one :couple_as_first_person, :foreign_key => 'first_person_id', :class_name => 'Couple' 
    has_one :couple_as_second_person, :foreign_key => 'second_person_id', :class_name => 'Couple' 

    def couple 
    couple_as_first_person || couple_as_second_person 
    end 
end 

Nếu một Person có thể thuộc về một vài Couple s, và có có cách nào để nói cho dù họ là những "đầu tiên" hay "thứ hai" trong bất kỳ Couple nhất định, bạn có thể muốn:

class Person 
    has_many :couples_as_first_person, :foreign_key => 'first_person_id', :class_name => 'Couple' 
    has_many :couples_as_second_person, :foreign_key => 'second_person_id', :class_name => 'Couple' 

    def couples 
    couples_as_first_person + couples_as_second_person 
    end 
end 
+0

Đây là câu trả lời được viết tốt và được suy nghĩ cẩn thận. Cám ơn rất nhiều. Tôi sẽ kiểm tra điều này sớm và cho bạn biết. – user94154

+0

chưa thử nghiệm, nhưng bạn WIN :) – user94154

+0

Tôi chỉ làm một cái gì đó như thế này bằng cách sử dụng AREL: 'def widgets; Widget.where ( Wiget.arel_table [: asset1_id] .eq (id) .or ( Widget.arel_table [: asset2_id] .eq (id) ) ); kết thúc' – thekingoftruth

0

chưa được kiểm tra, nhưng theo Rails API documentation, có lẽ cái gì đó như:

class Couple < ActiveRecord::Base 
    has_one :person, :foreign_key => :first_person_id 
    has_one :person, :foreign_key => :second_person_id 
end 
+0

Các thẻ này phải thuộc về_to, không có, vì các khóa ngoại nằm trên mô hình này. – tfwright

0

Lý thuyết mà thôi, chưa được kiểm tra:

Tạo hai lớp con của Person:

class FirstPerson < Person 
    belongs_to :couple 

class SecondPerson < Person 
    belongs_to :couple 

Couple lớp has_many của mỗi :

class Couple 
    has_many :first_persons, :foreign_key => :first_person_id 
    has_many :second_persons, :foreign_key => :second_person_id 

Sau đó tìm:

Couple.all(:include => [:first_persons, :second_persons]) 
+0

không nên là cặp vợ chồng 'has_one: first_person' và': second_person'? – user94154

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