如何更新我的用户/产品关联

时间:2013-06-03 14:28:37

标签: ruby-on-rails ruby-on-rails-4 model-associations

我正在尝试创建一个分享或提供产品的应用。所以我有两个模型:用户和产品。 用户可以拥有许多产品,作为所有者或借款人。产品只有一个所有者,只有一个借款人。

首先我做了类似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

你怎么看?

1 个答案:

答案 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您的模型做什么,并将决策留给每个对象做正确的事情。