简体   繁体   English

Rails ActiveRecord模型关联

[英]Rails ActiveRecord model association

I have a User model and a product model . 我有一个User model和一个product model

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

I want to create a wishlist for every user. 我想为每个用户创建一个愿望清单。 So i have to create a wishlist model with proper association. 所以我必须创建一个具有适当关联的wishlist model But i don't know how to start. 但我不知道如何开始。 I presume that the wishlist model contain an id , user_id and product_id field 我假设wishlist模型包含iduser_idproduct_id字段

Do i have to use has_many through association or a has_and_belongs_to_many ? 我必须has_many through associationhas_and_belongs_to_many使用has_many through association吗? I also want that if a user is destroyed to destroy his wishlist. 我也希望如果用户被销毁以销毁他的愿望清单。

What is the best way to do? 什么是最好的方法? Many thanks! 非常感谢!

You don't need the has_many :products relationship on User . 您不需要User上的has_many :products关系。 I don't think it makes sense for User and Product to be linked outside of a Wishlist . 我不认为将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

As @JZ11 pointed out, you shouldn't be linking a Product directly to a User (unless a User actually 'owns' a product for some reason). 正如@ JZ11指出的那样,您不应该直接将产品链接到用户(除非用户由于某种原因实际拥有'产品')。 However, what was missed is the model that makes up a Wishlist item: 然而,错过的是组成愿望清单项目的模型:

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

Naturally, you should be adding :dependent => :destroy where necessary. 当然,您应该在必要时添加:dependent => :destroy

To create your join table, do: 要创建连接表,请执行以下操作:

rails g migration create_products_users_table

Once you've done that, you need to add some code, below, to create the fields in the join table. 完成后,您需要在下面添加一些代码,以在连接表中创建字段。 Notice the :id => false , because you do not need an id in the join 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

The code above also creates some indexes and ensures that you don't have duplicates even at the database level. 上面的代码还创建了一些索引,并确保即使在数据库级别也没有重复项。

Your models would then have to look like this: 您的模型必须如下所示:

class Product < ActiveRecord::Base
  has_and_belongs_to_many :users
end

class User < ActiveRecord::Base
  has_and_belongs_to_many :products
end

When you destroy a user correctly, like user.destroy and not just delete it (there is a difference), then the related rows in the join table will be deleted as well. 当您正确销毁用户时,例如user.destroy而不仅仅是删除它(存在差异),那么连接表中的相关行也将被删除。 This is built in to ActiveRecord. 这是内置于ActiveRecord。

Notice though, that doing this will not really let you use the join table. 但请注意,这样做不会真正让您使用连接表。 It will accept code like user.products = [product1, product2] etc, and other goodies, but no real use of a wish list. 它将接受像user.products = [product1, product2]等代码和其他好东西,但没有真正使用愿望清单。

If you do want to use a wish list, you will have to create and use the middle join table differently, using has_many :through (I didn't check PinnyM's answer but that might be the way to do it). 如果你确实想要使用愿望清单,你将不得不使用has_many :through来创建和使用中间连接表(我没有检查PinnyM的答案,但这可能是这样做的方法)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM