与分散在数据库中的 Shops 和 AmazonCredentials 的重复关系可以替换为间接关系。幸运的是,Rails 提供了使间接关系看起来直接的方法:has_many :through。
而且您不需要第一次就完美,也不需要预测所有可能的用途。 Migrations 帮助您安全地更改设计以满足不断变化的需求。
让我们建立基本的关系。我做了一些假设,例如运输方式与市场相关。
我们马上遇到了一个问题:凭据。商店需要每个 Marketplace 的凭据。这可以通过一个中间模型来解决:MarketplaceAccount,它将 Shop 和 Marketplace 与 Shop 的凭据结合在一起。凭证可以做成键/值对的行。
订单需要记住有关订购了哪些产品、数量和价格的详细信息。这需要另一个中间模型:ProductOrder。
基本模型如下所示:
class Product < ApplicationRecord
belongs_to :shop
has_many :product_orders
has_many :orders, through: :product_orders
has_many :customers, through: :orders
# name
# description
# sku
end
class Shop < ApplicationRecord
has_many :products
has_many :marketplace_accounts
has_many :marketplaces, through: :marketplace_accounts
has_many :orders
has_many :customers, through: :orders
# name
# country
end
class Order < ApplicationRecord
belongs_to :customer
# Remember which MarketplaceAccount this was done with
belongs_to :marketplace_account
has_one :shop, through: :marketplace_account
has_one :marketplace, through: :marketplace_account
# How is it being shipped?
belongs_to :shipping_method
has_many :product_orders
has_many :products, through: :product_orders
# tracking number
# status
end
class ProductOrder < ApplicationRecord
belongs_to :order
belongs_to :product
# price
# quantity
end
# Holds the Shop's credentials for a Marketplace.
class MarketplaceAccount < ApplicationRecord
belongs_to :shop
belongs_to :marketplace
has_many :credentials
end
# Each row is simply a key and value.
# Consider encrypting this table.
class Credentials < ApplicationRecord
belongs_to :marketplace_account
# key
# value
end
class Marketplace < ApplicationRecord
has_many :shipping_methods
has_many :marketplace_accounts
has_many :shops, through: :marketplace_accounts
# name
end
class ShippingMethod < ApplicationRecord
belongs_to :marketplace
has_many :shops, through: :marketplace
# speed
# rate
# name
end
class Customer < ApplicationRecord
has_many :orders
has_many :product_orders, through: :orders
has_many :products, through: :product_orders
end
通过使用has_many :through 和has_one :through,我们可以避免重复,同时使间接关系看起来很直接。一个 Shop has_many MarketplaceAccounts,一个 MarketplaceAccount 属于一个 Marketplace;使用has_many :marketplaces, through: :marketplace_accounts,商店可以直接访问其市场。 shop.marketplaces.
键/值凭据表避免了公司特定凭据表的激增。
可以充实更多的关系。一个产品可以被许多商店出售,所以我们可以有一个 ShopProduct 将通用产品与商店的销售方式联系起来。这样可以避免重复的产品信息,并让您可以看到许多商店如何销售单个产品。
class Product < ApplicationRecord
has_many :shop_products
# sku
# generic name
# generic description
# manufacturer's recommended price
end
class ShopProduct < ApplicationRecord
belongs_to :shop
belongs_to :product
delegate :sku, to: :product
# shop specific name
# shop specific description
# shop price
end
class Shop
has_many :shop_products
has_many :products, through: :shop_products
end
大多数事情都与 ShopProduct 而不是 Product 相关。
您有一家使用单一货币的商店。该设计可以扩展为允许商店使用多种货币。
class Currency < ApplicationRecord
# symbol
# conversion rate
end
class ShopCurrencies < ApplicationRecord
belongs_to :shop
belongs_to :currency
end
class Shop < ApplicationRecord
has_many :shop_currencies
has_many :currencies, through: :shop_currencies
end
has_many :currencies, through: :shop_currencies 让shop.currencies 工作。
这就是基础。有了这些,您就可以根据自己的需要来确定基本布局。