这种关系可以用 Ruby on Rails 来描述吗?

发布于 2024-08-10 19:56:32 字数 1097 浏览 6 评论 0原文

这是一种可以用 Ruby on Rails 的 ActiveRecord 模型关系来描述的关系吗?

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

这样我就可以获得如下所示的数据:

地址:

   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                    |

我想将地址存储在他们自己的表中,因为数据可能在客户之间共享(尤其是送货地址)。但对于任何给定的客户来说,甚至只有两个地址。

我想避免多对多关系,除非没有其他办法。

Is this a relationship that can be described in Ruby on Rails' ActiveRecord model relationships?

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

So that I could have data that looks like this:

Address:

   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 |

Customer:

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

I want to store addresses in their own table because the data may be shared across customers (shipping address especially). But there would only even be two addresses for any given customer.

I'd like to avoid a many-to-many relationship unless there is no other way.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

多情癖 2024-08-17 19:56:32

是的,这是完全有可能做到的。给定一个 customers 表,其中 shipping_address_idbilling_address_id 指向 addresses 表,您的 Customer 模型可能如下所示:

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

这将允许客户引用相同的地址行作为送货和帐单地址,并且还允许多个客户共享地址。

更新:在共享对此类地址的引用时,您可能需要仔细考虑如何处理地址更新。在您的示例中,Bob 和 Al 共享相同的送货地址。现在,如果 Bob 更新了他的送货地址,您可能希望为 Bob 的新地址创建一个新的 Address 记录,而不是更新现有记录,以避免也更改 Al 的地址。有时,在这种情况下您实际上可能想要更新两个客户的地址,但在大多数情况下您可能不会这样做。

Yes, it's perfectly possible to do that. Given a customers table with the two foreign keys shipping_address_id and billing_address_id to the addresses table, your Customer model could look like this:

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

This will let a customer reference the same address row for shipping and billing addresses, and will also let several customers share addresses.

Update: When sharing references to addresses like this you'll probably want to carefully consider how to handle address updates. In your example, Bob and Al share the same shipping address. Now, if Bob updates his shipping address you probably want to create a new Address record for Bob's new address rather than update the existing record, to avoid changing Al's address too. Sometimes, you actually might want to update both customers' addresses in this situation, but in most cases you probably don't.

生生漫 2024-08-17 19:56:32

给定如下表定义:

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

Given table definitions like this:

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

You can associate a billing and shipping address with your customer like this:

class Customer < ActiveRecord::Base
  belongs_to :shipping_address, :class_name => "Address"
  belongs_to :billing_address,  :class_name => "Address"
end
软糖 2024-08-17 19:56:32

ActiveRecord 关联的文档中有一个关于 has_onebelongs_to此外,关于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">
>> 

The documentation for ActiveRecord associations has a section on has_one vs belongs_to. In addition, the section on has_one mentions that this should be used only if the other class has the foreign key. So, to model what you want, you would use.

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

Example usage:

>> 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">
>> 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文