如何完成这个Rails 3双面多态has_many:通过关系(没有has_many_polymorphs或其他插件)?

时间:2011-04-24 16:39:36

标签: ruby-on-rails-3 polymorphic-associations has-many-through

我知道此主题之前已经以各种方式接近过几次,但我无法综合其他问题来满足Rails 3的这个特定用例:

我正在尝试构建一个数据模型,其中有Attachments和Attachables。任何附件都可以与Attachable连接,反之亦然。我希望这最终可以用作组合acts_as插件(acts_as_attachable和acts_as_attachment)。

我当前的架构使用具有两个多态的belongs_to关系的Attacher模型来尝试实现此目的。

此处列出的具体案例涉及一个可附加模型(好)和两个附件模型(图像和电影)。

这是我到目前为止所做的:

attacher.rb

class Attacher < ActiveRecord::Base
    belongs_to :attachment, :polymorphic => true
    belongs_to :attachable, :polymorphic => true
end

good.rb

class Good < ActiveRecord::Base
    has_many :attachment_relations, :as => :attachable, :class_name => 'Attacher'
    has_many :attached_images, :through => :attachment_relations, :source => :attachment, :source_type  => 'Image'
    has_many :attached_movies, :through => :attachment_relations, :source => :attachment, :source_type  => 'Movie'
end

image.rb

class Image < ActiveRecord::Base
    has_many :attachable_relations, :as => :attachment, :class_name => 'Attacher'
end

movie.rb

class Movie < ActiveRecord::Base
    has_many :attachable_relations, :as => :attachment, :class_name => 'Attacher'
end

只要我可以执行以下操作,就可以了:

@g = Good.create!
@i = Image.create!
@m = Movie.create!

@g.attached_images << @i
@g.attached_images       # [#<Image id: 1 ... >]

@g.attached_movies << @m
@g.attached_movies       # [#<Movie id: 1 ... >]

@g.attachment_relations  # [#<Attacher id: 1, attachable_id: 1, attachable_type: "Good", attachment_id: 1, attachment_type: "Image" ...>, #<Attacher id: 2, attachable_id: 1, attachable_type: "Good", attachment_id: 1, attachment_type: "Movie" ...>]

我的问题的主旨是:我可以使用关联来构建以下方法/返回,这样我仍然可以执行@g.attachments.where( ... )之类的操作:

@g.attachments           # [#<Image id: 1 ... >, #<Movie id: 1 ... >]

我尝试了很多这样的事情:

good.rb

class Good < ActiveRecord::Base
    has_many :attachment_relations, :as => :attachable, :class_name => 'Attacher'
    has_many :attachments, :through => :attachment_relations
end

但是他们倾向于把我这个:

ActiveRecord::HasManyThroughAssociationPolymorphicError: Cannot have a has_many :through association 'Good#attachments' on the polymorphic object 'Attachment#attachment'

我认为我基本上需要一些可以像source_type => :any ...

那样的东西

另外,这是我关于StackOverflow的第一个问题,所以请告诉我是否有什么可以改进我的问题。提前致谢! :)

2 个答案:

答案 0 :(得分:1)

不幸的是,我得出的结论是,没有一种简单或标准的方法可以做到这一点。我找到的最清晰的基本解决方案来自Squeegy对这个问题的回答:Rails polymorphic many to many association,他将他的要点引用到一个相当简单的has_relations module

我认为这基本上回答了我的问题,并为创建更强大的解决方案提供了良好的起点。

答案 1 :(得分:0)

遗憾的是,这对于rails来说真的不可能,你可以试试这个扩展的运气: https://github.com/kronn/has_many_polymorphs/tree/

您应该准备好将此行添加到您的Gemfile:

gem 'kronn-has_many_polymorphs'

并在rails应用程序文件夹中运行此命令:

bundle