我正在尝试创建一个分享或提供产品的应用。所以我有两个模型:用户和产品。 用户可以拥有许多产品,作为所有者或借款人。产品只有一个所有者,只有一个借款人。
首先我做了类似that的事情:
> rails generate model User name:string
class User
has_many :owned_products, class_name: "Product", foreign_key: "owner_id"
has_many :borrowed_products, class_name: "Product", foreign_key: "borrower_id"
end
> rails generate model Product name:string owner_id:integer borrower_id:integer
class Product
belongs_to :owner, class_name: "User", foreign_key: "owner_id"
belongs_to :borrower, class_name: "User", foreign_key: "borrower_id"
end
我在我的产品控制器中添加了一个安全过滤器,该过滤器仅为产品所有者启用更新方法。但是当我想改变产品的借款人时,我遇到了一些问题,因为借款人从不是所有者,所以产品无法更新。
所以现在我想知道我是否不应该从我的产品模型中取出foreign_key,以便将用户的更新操作分离到他自己的产品上,以及用户更新操作以借用一个产品不属于他......
> rails generate model User name:string
class User
has_many :properties
has_many :loans
has_many :owned_products, through: :properties
has_many :borrowed_products, through: :loans
end
> rails generate model Property owner_id:integer owned_product_id:integer
class Property
belongs_to :owner, class_name: "User", foreign_key: "user_id"
belongs_to :owned_product, class_name: "Product", foreign_key: "product_id"
end
> rails generate model Loan borrower_id:integer borrowed_product_id:integer
class Loan
belongs_to :borrower, class_name: "User", foreign_key: "user_id"
belongs_to :borrowed_product, class_name: "Product", foreign_key: "product_id"
end
> rails generate model Product name:string
class Product
has_one :property
has_one :loan
has_one :owner, through: :property
has_one :borrower, through: :loan
end
你怎么看?
答案 0 :(得分:1)
由于借来的产品和拥有的产品是具有相同属性列表的相同类型的对象,但仅在行为方面有所不同,我会对Product
使用单表继承。
迁移:
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
# ...
t.timestamps
end
end
end
class CreateProducts < ActiveRecord::Migration
def change
create_table :products do |t|
t.integer :ownerable_id
t.string :ownerable_type
# ...
t.timestamps
end
end
end
型号:
class User < ActiveRecord::Base
has_many :products, :as => :ownerable
end
class Product < ActiveRecord::Base
belongs_to :user, :polymorphic => true
end
class OwnedProduct < Product
end
class BorrowedProduct < Product
end
这种方法的好处是,您可以在每个模型中定义适当的行为,而无需询问它是“拥有”还是“借用”。只需tell您的模型做什么,并将决策留给每个对象做正确的事情。