Rails ActiveRecord模型关联

时间:2013-10-14 19:55:37

标签: ruby-on-rails activerecord model associations

我有一个User model和一个product model

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

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

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

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

3 个答案:

答案 0 :(得分:1)

has_many :products上不需要User关系。 我认为将UserProduct链接到Wishlist之外是不合理的。

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

答案 1 :(得分: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

答案 2 :(得分: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]等代码和其他好东西,但不会真正使用愿望清单。

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