2009-11-14 2 views
5

Ruby on Rails의 ActiveRecord 모델 관계에서 설명 할 수있는 관계입니까?Ruby on Rails에서이 관계를 설명 할 수 있습니까?

Customer       Address 
    ===================    ========= 
    Billing_Address_Id >------} 
           }---|- AddressId 
    Shipping_Address_Id >------} 

I는 다음과 같다 데이터를 수 있도록 :

주소 :

Id | Addr   | City  | State | Zip | 
    ================================================ 
    1 | 123 Main  | New York | NY | 99999 | 
    2 | 200 2nd Street | New York | NY | 99999 | 
    3 | 300 3rd Street | Albany | NY | 99998 | 
    4 | PO Box 4  | Albany | NY | 99998 | 

고객 :

Id | Name | Billing_Address_Id | Shipping_Address_Id | 
    ======================================================= 
    1 | Bob | 1     | 1     | 
    2 | Al | 2     | 1     | 
    3 | Joe | 3     | 4     | 

내가 자신의 테이블에 주소를 저장할 때문에 데이터는 고객간에 공유 될 수 있습니다 (특히 배송 주소). 그러나 특정 고객에 대해 두 개의 주소 만있을 수도 있습니다.

다른 방법이 없다면 다 대다 관계를 피하고 싶습니다. 이 같은

답변

2

을 감안할 때 테이블 정의 :

create_table :addresses do |t| 
    t.string :street 
    t.string :city 
    t.string :state 
    t.string :zip 
    t.timestamps 
end 

create_table :customers do |t| 
    t.string  :name 
    t.references :shipping_address 
    t.references :billing_address 
    t.timestamps 
end 

당신이처럼 고객과 결제 및 배송 주소를 연결할 수 있습니다

class Customer < ActiveRecord::Base 
    belongs_to :shipping_address, :class_name => "Address" 
    belongs_to :billing_address, :class_name => "Address" 
end 
+0

테이블 디자인이 도움이 될 것입니다. 나는 .references "데이터 유형"을 인식하지 못했습니다. – y0mbo

5

는 예, 그렇게 할 수 있도록 완벽하게 가능합니다. addresses 테이블에 두 개의 외래 키 shipping_address_idbilling_address_idcustomers 테이블을 감안할 때, 당신의 Customer 모델은 다음과 같이 수 :

class Customer < ActiveRecord::Base 
    belongs_to :billing_address, :class_name => 'Address' 
    belongs_to :shipping_address, :class_name => 'Address' 
end 

이 배송 및 청구 주소를 고객 레퍼런스를 같은 주소 행을 드릴 것입니다, 그리고 것입니다 또한 여러 고객이 주소를 공유하게하십시오.

업데이트 : 이와 같은 주소에 대한 참조를 공유 할 때 주소 업데이트를 처리하는 방법을 신중히 고려해야합니다. 귀하의 예에서 Bob과 Al은 동일한 배송지 주소를 공유합니다. 이제 Bob이 배송 주소를 업데이트하면 Al의 주소도 변경되지 않도록 기존 레코드를 업데이트하는 대신 Bob의 새 주소에 대한 새 Address 레코드를 생성하려고합니다. 때로는이 상황에서 두 고객의 주소를 모두 업데이트하려고 할 수도 있지만 대부분의 경우에는 그렇지 않을 수 있습니다.

+0

나는 귀하의 디자인 평가에 동의합니다. 내 예제는 실제로 수행 할 작업에서 약간 단순화되었습니다. 고객은 실제로 동일한 세대의 동일한 계정에 속하게됩니다. 그들은 동일한 주소를 공유하거나 다른 위치로 운송되기를 원할 수 있습니다. – y0mbo

0

The documentation for ActiveRecord associations has a section on has_one vs belongs_to. 또한 section on has_one다른 클래스에 외래 키가있는 경우에만 사용해야한다고 언급합니다. 그래서, 당신이 원하는 것을 모델링하기 위해서, 당신은 사용할 것입니다.

class Address < ActiveRecord::Base 
    has_one :shipto_customer, :class_name => "Customer", :foreign_key => "shipping_address_id" 
    has_one :billto_customer, :class_name => "Customer", :foreign_key => "billing_address_id" 
end 

class Customer < ActiveRecord::Base 
    belongs_to :shipping_address, :class_name => "Address" 
    belongs_to :billing_address, :class_name => "Address" 
end 

사용 예제 :

>> customer = Customer.new(:name => "John Smith", 
?>  :shipping_address => Address.new(:address => "123 M St", 
?>  :city => "Phoenix", :state => "AZ", :zip => "85015"), 
?>  :billing_address => Address.new(:address => "555 W Main Dr", 
?>  :city => "Phoenix", :state => "AZ", :zip => "85015") 
>> ) 
=> #<Customer id: nil, name: "John Smith", billing_address_id: nil, shipping_address_id: nil, created_at: nil, updated_at: nil> 
>> customer.save 
    Address Create (0.8ms) INSERT INTO "addresses" ("address", "city", "zip", "created_at", "updated_at", "state") VALUES('555 W Main Dr', 'Phoenix', '85015', '2009-11-14 17:03:28', '2009-11-14 17:03:28', 'AZ') 
    Address Create (0.2ms) INSERT INTO "addresses" ("address", "city", "zip", "created_at", "updated_at", "state") VALUES('123 M St', 'Phoenix', '85015', '2009-11-14 17:03:28', '2009-11-14 17:03:28', 'AZ') 
    Customer Create (0.2ms) INSERT INTO "customers" ("name", "billing_address_id", "shipping_address_id", "created_at", "updated_at") VALUES('John Smith', 1, 2, '2009-11-14 17:03:28', '2009-11-14 17:03:28') 
=> true 
>> customer.shipping_address 
=> #<Address id: 2, address: "123 M St", city: "Phoenix", state: "AZ", zip: "85015", created_at: "2009-11-14 17:03:28", updated_at: "2009-11-14 17:03:28"> 
>> customer.billing_address 
=> #<Address id: 1, address: "555 W Main Dr", city: "Phoenix", state: "AZ", zip: "85015", created_at: "2009-11-14 17:03:28", updated_at: "2009-11-14 17:03:28"> 
>> 
+0

OP는 고객간에 주소를 공유 할 수 있기를 원했기 때문에 'Address' 모델의 관계는'has_one' 관계가 아니라 'has_many'이어야합니다. –

+0

OP의 게시물에서 명확하지 않은 것처럼 보입니다. 데이터 예제에서 주소 공유, 즉 has_many가 코드 예제에서 has_one을 제안하고 있습니다. 그런 다음 그는 다 대다를 많이 갖지 않을 것이라고 말합니다. 내 의견으로는, 공유 주소는 나쁜 생각 일 것입니다. 고객 A가 현재 주소를 업데이트하여 우편 번호 + 4 또는 Apt 번호를 추가하면 어떻게됩니까? –

+0

예, 공유 주소는 분명히 번거롭습니다. 별도의 테이블에 주소와 고객을 유지하는 것이 좋습니다. 그러나 주소 행에 대한 참조를 공유하면 주소 업데이트를 처리하는 방법을 결정할 때 문제가 발생할 가능성이 큽니다. –

관련 문제