我正在创建一个基本的订阅应用程序,我想知道下面建立关系的最简洁方法是什么。我似乎对has_and_belongs_to_many
关系以及何时使用它们感到困惑。
我正在尝试大致创建下面的结构,并注意几点。 subscription
和order
只能有一个plan
,但subscriptions
和orders
都可以有多个products
。
计划也以与产品相同的方式创建。即可以创建6个计划,然后可以将其添加到任意数量的订阅(类似于产品)。
目前我有以下内容:
# User Model
has_one :subscription
has_one :plan, through: :subscription
# Subscription Model
belongs_to :user
belongs_to :plan # Not sure this is correct as a subscription should only be allowed to have 1 plan which belongs to the subscription.
# Plan Model
has_many :subscriptions # Again this doesn't feel quite right as I think the plan should belong to the subscription.
# Product Model
has_and_belongs_to_many :orders
has_and_belongs_to_many :subscriptions
# Order Model
belongs_to :user
has_and_belongs_to_many :products
人们可以提供任何有关建模的最佳方式的建议。
答案 0 :(得分:0)
在我看来has_many:通过关联更合适。
http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association
# User model
has_one :subscription
has_one :plan, through: :subscription
# Subscription model
belongs_to :user
belongs_to :plan
has_many :orders
# Plan (Subscription Plan) model
has_many :subscriptions
has_many :users, through: :subscriptions
# Order model
belongs_to :subscription
您能详细说明Order
和Product
型号吗?你想让他们代表什么?如果Order
用于表示订阅中的每个交易,则它应属于Subscription
。
答案 1 :(得分:0)
如果您只需处理riot
,我认为答案很简单 - 您可以@plans
和@subscriptions
属于@orders
,每个@plans
可以定义为have_many
:
# User model
has_one :subscription
has_many :orders
# Plan model
has_many :subscriptions
has_many :orders
# Subscription model
belongs_to :user
belongs_to :plan
# Order model
belongs_to :user
belongs_to :plan
(我很感激你的观点,“感觉”就像一个计划应该属于订阅而不是反之亦然,但你必须“在这里使用力量,卢克”。)
我认为在@products
中折叠的方式可能是使用连接表:
# Order join table - OrderProduct
belongs_to :order
belongs_to :product
# Subscription join table - SubscriptionProduct
belongs_to :subscription
belongs_to :product
然后,我认为,其余的模型看起来像:
# User model
has_one :subscription
has_many :orders
# Plan model
has_many :subscriptions
has_many :orders
# Subscription model
belongs_to :user
belongs_to :plan
has_many :subscription_products
has_many :products, :through => :subscription_products
# Order model
belongs_to :user
belongs_to :plan
has_many :order_products
has_many :products, :through => :order_products
# Product model
has_many :subscription_products
has_many :subscriptions, :through => :subscription_products
has_many :order_products
has_many :orders, :through => :order_products
创建新的@order
可能类似于:
@order = Order.create(user: @user, plan: @plan)
@order.products = @products
@order.save
新@subscription
类似。
如果您想要订阅给定@users
的所有@product
的列表,您可以:
@users = @product.subscriptions.map{|x| x.user}
如果您想查看当前订阅的所有@products
:
@products = @user.subscription.products
如果您想查看订购产品的所有@users
:
@users = @product.orders.map{|x| x.user}.uniq
(.uniq
以防用户多次订购同一产品)
答案 2 :(得分:0)
has_belongs_to_many 指定与另一个类的多对多关系,即不是为连接表创建单独的类,而是可以直接在这些父类中指定
class A < ActiveRecord::Base
has_many :abs
.....
end
class B < ActiveRecord::Base
has_many :abs
....
end
class AB < ActiveRecord::Base
belongs_to :a
belongs_to :b
....
end
而不是这个,我们可以在类A和B中直接指定
class A < ActiveRecord::Base
has_belongs_to_many :as
....
end
class B < ActiveRecord::Base
has_belongs_to_many :bs
....
end
希望现在很清楚has_belongs_to_many关联。
现在,对于模型设计,我们必须保留Order类,该类专门指向订购具有订阅的产品的用户
即,orders
表将充当与用户,产品,订阅相关联的连接表。
orders是一个指向Order Rails模型的表
Rails Association将如下
class User < ActiveRecord::Base
has_many :subscriptions
has_many :orders
has_many plans, through: :subscription
....
end
class Plan < ActiveRecord::Base
has_many :subscriptions
has_many :users, through: :subscriptions
....
end
class Subscription < ActiveRecord::Base
belongs_to :user
belongs_to :plan
has_many :orders
....
end
class Order < ActiveRecord::Base
belongs_to :user
belongs_to :product
belongs_to :subscription
....
end
class Product < ActiveRecord::Base
has_many :orders
has_many :users, through: :orders
....
end
希望这对你有用:)。