:多态/:通过ActiveRecord关联(Rails的3.2) [英] :polymorphic/:through ActiveRecord associations (Rails 3.2)

查看:190
本文介绍了:多态/:通过ActiveRecord关联(Rails的3.2)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个可以适用于不同的 Taggable s的标签系统。我希望能够查询它们透明,在这里接受的解决方案:

HABTM多态性关系

我想可以说,例如,告诉我所有的发表 S, S,视频 S等标记为'富'。 pretty的straighforward。并发症:

  1. 在不同种类的 Taggable的是不是多态的面向对象的意义上说,只有通过多态关联。这里的的一个 taggables 表,以保证taggable_id的唯一性(在帖主键,等等)。
  2. 标签 S,这并不奇怪,有一个多到许多关系与 Taggable s和关联通过 map_tags 表。

型号:

 类标签<的ActiveRecord :: Base的
  的has_many:map_tags
  的has_many:标签,:通过=> :map_tags
结束

类MapTag<的ActiveRecord :: Base的
  belongs_to的:标签
  belongs_to的:标记,多态=> :真正
结束

类岗位<的ActiveRecord :: Base的
  的has_many:map_tags,:为=> :标签
  的has_many:标签,:通过=> :map_tags
  #其他taggables都设置了类似
结束
 

问题:

  1. 我想我的第一个问题应该是:这甚至可能吗?我所看到的模型有很多相关的情况下多态,但我不知道它的工作原理的其他方式,如错误消息下方可能会建议...
  2. 难道我设置了多态是否正确?我的理解是,儿童模式基本上宣布自己为标记,并与他们取表接口直接(在这种情况下, map_tags )是一个得到了:多态声明
  3. 如何说告诉我一切都标记为'富'中的ActiveRecord-说话?

我已经试过什么:

  IRB> Tag.find_by_name('富',:包括=>:标签)
标记加载(0.1毫秒)选择`tags`。* FROM`tags` WHERE`tags`.`name` ='富'LIMIT 1
NameError:未初始化的常数标签::标记
...
IRB> Tag.find(:所有,:包括=>:标签,:条件=>Tag.name ='富'])
ActiveRecord的:: HasManyThroughAssociationPolymorphicSourceError:
能不能有一个的has_many:通过关联标签#标签为多态对象标签#标签。
...
 

修改

我发现<一href="http://stackoverflow.com/questions/6997141/rails-has-many-through-with-polymorphic-association-will-this-work">this帖子,其中指出,我需要指定:源:SOURCE_TYPE 。所以:

 类标签&lt;的ActiveRecord :: Base的
  的has_many:map_tags
  的has_many:帖子,:通过=&GT; :map_tags,:源=&GT; :标记,:SOURCE_TYPE =&GT; 邮报
  的has_many:页面:通过=&GT; :map_tags,:源=&GT; :标记,:SOURCE_TYPE =&GT; '页'
结束
 

我觉得我更近(?),但我仍然不知道如何查询相关联的对象...

  IRB&GT; Tag.first.posts
  标记加载(为0.2ms)选择`tags`。* FROM`tags`限制1
NoMethodError:未定义的方法`帖的#&LT;标签ID:1,名称:福&GT;
IRB&GT; Tag.first.tagged
  标记加载(为0.2ms)选择`tags`。* FROM`tags`限制1
ActiveRecord的:: HasManyThroughAssociationPolymorphicSourceError:
能不能有一个的has_many:通过关联标签#标签为多态对象标签#标签。
 

解决方案

您多态关联的设置是否正确。除了一个小错字:

  belongs_to的:标记,多态=&GT; :真正
 

这应该是真实的布尔不是:真正的象征

I have a tag system that can apply to various Taggables. I want to be able to query them transparently, as in the accepted solution here:

HABTM Polymorphic Relationship

I want to be able to say, for example, show me all Posts, Pages, Videos, etc. tagged with 'foo'. Pretty straighforward. The complications:

  1. The different kinds of Taggables are not polymorphic in the OO sense, only through polymorphic associations. There is a taggables table to guarantee uniqueness of taggable_id (the primary key in posts, etc.).
  2. Tags, not surprisingly, have a many-to-many relation with Taggables, and are associated through the map_tags table.

Models:

class Tag < ActiveRecord::Base
  has_many :map_tags
  has_many :tagged, :through => :map_tags
end

class MapTag < ActiveRecord::Base    
  belongs_to :tags
  belongs_to :tagged, :polymorphic => :true
end

class Post < ActiveRecord::Base
  has_many :map_tags, :as => :tagged 
  has_many :tags, :through => :map_tags
  # other taggables are set up similarly
end

Questions:

  1. I guess my first questions ought to be: is this even possible? I have seen Models "have many" associated instances polymorphically, but I'm not sure if it works the other way, as the error message below may suggest...
  2. Did I set up the polymorphism correctly? My understanding is that the "child" models basically declare themselves as "tagged", and whichever table interfaces with them directly (in this case map_tags) is the one to get the :polymorphic declaration.
  3. How do I say "show me everything tagged with 'foo'" in ActiveRecord-speak?

What I've tried:

irb> Tag.find_by_name( 'foo', :include => :tagged )
Tag Load (0.1ms)  SELECT `tags`.* FROM `tags` WHERE `tags`.`name` = 'foo' LIMIT 1
NameError: uninitialized constant Tag::Tagged
...
irb> Tag.find( :all, :include => :tagged, :conditions => ["Tag.name = 'foo'"] )
ActiveRecord::HasManyThroughAssociationPolymorphicSourceError:
Cannot have a has_many :through association 'Tag#tagged' on the polymorphic object 'Tagged#tagged'.
...

EDIT

I found this post, which points out that I need to specify :source and :source_type. So:

class Tag < ActiveRecord::Base
  has_many :map_tags
  has_many :posts, :through => :map_tags, :source => :tagged, :source_type => 'Post'
  has_many :pages, :through => :map_tags, :source => :tagged, :source_type => 'Page'
end

I think I'm closer(?), but I'm still not sure how to query the associated objects...

irb> Tag.first.posts
  Tag Load (0.2ms)  SELECT `tags`.* FROM `tags` LIMIT 1
NoMethodError: undefined method `posts' for #<Tag id: 1, name: "foo">
irb> Tag.first.tagged
  Tag Load (0.2ms)  SELECT `tags`.* FROM `tags` LIMIT 1
ActiveRecord::HasManyThroughAssociationPolymorphicSourceError:
Cannot have a has_many :through association 'Tag#tagged' on the polymorphic object 'Tagged#tagged'.

解决方案

Your polymorphic association setup is correct. Except for a small typo :

belongs_to :tagged, :polymorphic => :true

It should be true the boolean not :true the symbol !

这篇关于:多态/:通过ActiveRecord关联(Rails的3.2)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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