0

我有一个User model和一个product model

User has_many :products, :dependent => :destroy
Product belongs_to :user, :foreign_key => "user_id", touch: true

我想为每个用户创建一个愿望清单。所以我必须创建一个wishlist model适当的关联。但我不知道如何开始。我假设愿望清单模型包含一个id,user_idproduct_id字段

我必须使用has_many through association还是一个has_and_belongs_to_many ?我还希望如果用户被销毁以销毁他的愿望清单。

最好的方法是什么?非常感谢!

4

3 回答 3

1

您不需要 上的has_many :products关系User。我User认为ProductWishlist.

class Wishlist < ActiveRecord::Base
  has_many :products
  belongs_to :user
end

class User < ActiveRecord::Base
  has_one :wishlist, dependent: :destroy
end

class Product < ActiveRecord::Base
  belongs_to :wishlist
end
于 2013-10-14T20:07:37.273 回答
1

正如@JZ11 指出的那样,您不应该将产品直接链接到用户(除非用户出于某种原因实际上“拥有”产品)。但是,缺少的是构成愿望清单项目的模型:

class User < ActiveRecord::Base
  has_many :wishlists       # or has_one, depending on how many lists a User can have...
end

class Product < ActiveRecord::Base
  has_many :wishlist_items
end

class Wishlist < ActiveRecord::Base
  belongs_to :user
  has_many :wishlist_items
  has_many :products, :through => :wishlist_items
end

class WishlistItem < ActiveRecord::Base
  belongs_to :product
  belongs_to :wishlist
end

当然,您应该:dependent => :destroy在必要时添加。

于 2013-10-14T20:18:10.963 回答
0

要创建连接表,请执行以下操作:

rails g migration create_products_users_table

完成后,您需要在下面添加一些代码,以在连接表中创建字段。注意:id => false, 因为您不需要连接表中的 id:

class CreateProductsUsersTable < ActiveRecord::Migration
  def change
    create_table :products_users, :id => false do |t|
      t.references :product
      t.references :user
    end
    add_index :products_users, [:product_id, :user_id]
    add_index :products_users, :user_id
  end
end

上面的代码还创建了一些索引,并确保即使在数据库级别也没有重复项。

然后,您的模型必须如下所示:

class Product < ActiveRecord::Base
  has_and_belongs_to_many :users
end

class User < ActiveRecord::Base
  has_and_belongs_to_many :products
end

当您正确地销毁用户时,例如user.destroy而不只是删除它(有区别),那么连接表中的相关行也将被删除。这是内置到 ActiveRecord 中的。

但请注意,这样做不会真正让您使用连接表。它将接受诸如user.products = [product1, product2]etc 之类的代码和其他好东西,但不会真正使用愿望清单。

如果您确实想使用愿望清单,则必须使用不同的方式创建和使用中间连接表has_many :through(我没有检查 PinnyM 的答案,但这可能是这样做的方法)。

于 2013-10-14T20:37:52.250 回答