建立一个多态的has_many:through关系 [英] Setting up a polymorphic has_many :through relationship

查看:85
本文介绍了建立一个多态的has_many:through关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

rails g model Article name:string
rails g model Category name:string
rails g model Tag name:string taggable_id:integer taggable_type:string category_id:integer

我已经创建了我的模型,如前面的代码所示.文章将是可以带有标签的许多模型之一.类别模型将包含可以分配的所有类别.标签模型将是一个多态的联接表,它代表被标记的关系.

I have created my models as shown in the preceding code. Articles will be one of many models which can have tags. The category model will contain all categories which may be assigned. The tag model will be a polymorphic join-table which represents tagged relationships.

class Article < ActiveRecord::Base
  has_many :tags, :as => :taggable
  has_many :categories, :through => :taggable
end

class Category < ActiveRecord::Base
  has_many :tags, :as => :taggable
  has_many :articles, :through => :taggable
end

class Tag < ActiveRecord::Base
  belongs_to :taggable, :polymorphic => true
  belongs_to :category
end

我似乎无法使它正常工作,我可以非多态地做到这一点,但是多态性部分一定有问题.有什么想法吗?

I can't seem to get this to work, I can do it non polymorphic, but I must have something wrong with the polymorphic part. Any ideas?

仍然无法正确执行此操作:

Still not getting this right:

class Article < ActiveRecord::Base
    has_many :taggables, :as => :tag
    has_many :categories, :through => :taggables, :source => :tag, :source_type => "Article"
end
class Category < ActiveRecord::Base
    has_many :taggables, :as => :tag
    has_many :articles, :through => :taggables, :source => :tag, :source_type => "Article"
end
class Tag < ActiveRecord::Base
  belongs_to :taggable, :polymorphic => true
  belongs_to :category
end

推荐答案

要创建多态has_many:through,必须首先创建模型.我们将使用"Article","Category"和"Tag",其中"Tag"是连接模型,Article是可以用类别标记"的许多对象之一.

To create a polymorphic has_many :through, you must first create your models. We will use'Article,' 'Category,' and 'Tag' where 'Tag' is the join-model and Article is one of many objects which can be "tagged" with a category.

首先,您要创建文章"和类别"模型.这些是基本模型,现在还不需要任何特别的注意:

First you create your 'Article' and 'Category' models. These are basic models which do not need any special attention, just yet:

rails g model Article name:string
rails g model Category name:string

现在,我们将创建我们的多态联接表:

Now, we will create our polymorphic join-table:

rails g model Tag taggable_id:integer taggable_type:string category_id:integer

join-table将两个表连接在一起,或者在本例中,通过多态行为将一个表连接到许多其他表.它通过存储来自两个单独表的ID来完成此操作.这将创建一个链接.我们的类别"表将始终是类别",因此我们包括"category_id".它链接到的表各不相同,因此我们添加了一个'taggable_id'项,其中包含任何可标记项的ID.然后,我们使用'taggable_type'完成链接,使链接知道链接到的内容,例如文章.

The join-table joins together two tables, or in our case one table to many others via polymorphic behavior. It does this by storing the ID from two separate tables. This creates a link. Our 'Category' table will always be a 'Category' so we include 'category_id.' The tables it links to vary, so we add an item 'taggable_id' which holds the id of any taggable item. Then, we use 'taggable_type' to complete the link allowing the link to know what it is linked to, such as an article.

现在,我们需要设置模型:

Now, we need to set up our models:

class Article < ActiveRecord::Base
  has_many :tags, :as => :taggable, :dependent => :destroy
  has_many :categories, :through => :tags
end
class Category < ActiveRecord::Base
  has_many :tags, :dependent => :destroy
  has_many :articles, :through => :tags, :source => :taggable, :source_type => 'Article'
end
class Tag < ActiveRecord::Base
  belongs_to :taggable, :polymorphic => true
  belongs_to :category
end

然后,使用以下命令设置数据库:

After this, setup your database using:

rake db:migrate

就是这样!现在,您可以使用真实数据设置数据库:

That's it! Now, you can setup your database with real data:

Category.create :name => "Food"
Article.create :name => "Picking the right restaurant."
Article.create :name => "The perfect cherry pie!"
Article.create :name => "Foods to avoid when in a hurry!"
Category.create :name => "Kitchen"
Article.create :name => "The buyers guide to great refrigeration units."
Article.create :name => "The best stove for your money."
Category.create :name => "Beverages"
Article.create :name => "How to: Make your own soda."
Article.create :name => "How to: Fermenting fruit."

现在您有一些类别和各种文章.但是,未使用标签对它们进行分类.因此,我们需要这样做:

Now you have a few categories and various articles. They are not categorized using tags, however. So, we will need to do that:

a = Tag.new
a.taggable = Article.find_by_name("Picking the right restaurant.")
a.category = Category.find_by_name("Food")
a.save

然后您可以为每个重复此操作,这将链接您的类别和文章.完成此操作后,您将可以访问每个文章的类别和每个类别的文章:

You could then repeat this for each, this will link your categories and articles. After doing this you will be able to access each article's categories and each categorie's articles:

Article.first.categories
Category.first.articles

注意:

1)无论何时要删除通过链接模型链接的项目,请确保使用销毁".销毁链接对象时,它也会销毁链接.这样可以确保没有不良链接或无效链接.这就是为什么我们使用':dependent =>:destroy'

1)Whenever you want to delete an item that is linked by a link-model make sure to use "destroy." When you destroy a linked object, it will also destroy the link. This ensures that there are no bad or dead links. This is why we use ':dependent => :destroy'

2)设置"Article"模型(这是我们的可标记"模型之一)时,必须使用:as进行链接.因为在前面的示例中,我们使用了'taggable_type'和'taggable_id',所以使用了:as =>:taggable.这有助于Rails知道如何将值存储在数据库中.

2)When setting up our 'Article' model, which is one our 'taggable' models, it must be linked using :as. Since in the preceeding example we used 'taggable_type' and 'taggable_id' we use :as => :taggable. This helps rails know how to store the values in the database.

3)将类别链接到文章时,我们使用: has_many:articles,:through =>:tags,:source =>:taggable,:source_type =>'Article' 这告诉类别模型它应该通过:tags包含许多:articles.出于与上述相同的原因,该源是:taggable的.源类型是"Article",因为模型会自动将taggable_type设置为其自己的名称.

3)When linking categories to articles, we use: has_many :articles, :through => :tags, :source => :taggable, :source_type => 'Article' This tells the category model that it should have many :articles through :tags. The source is :taggable, for the same reason as above. The source-type is "Article" because a model will automatically set taggable_type to its own name.

这篇关于建立一个多态的has_many:through关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆