如何完成这个 Rails 3 双面多态 has_many :through 关系(无需 has_many_polymorphs 或其他插件)?

发布于 2024-11-03 00:12:55 字数 2728 浏览 0 评论 0原文

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

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

我当前的模式使用具有两个多态belongs_to关系的Attacher模型来尝试完成此任务。

这里概述的具体案例涉及一个 Attachable 模型(Good)和两个 Attachment 模型(图像和电影)。

这是我到目前为止所拥有的:

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'

我认为我基本上需要一些可以像一样的东西源类型=> :any ...

此外,这是我在 StackOverflow 上的第一个问题,所以如果我可以做些什么来改进我的问题,请告诉我。提前致谢! :)

I know this topic has been approached several times before in various ways, but I haven't been able to synthesize the other questions to meet this particular use case for Rails 3:

I am trying to construct a data model in which there are Attachments and Attachables. Any Attachment can be connected with an Attachable, and vice-versa. I would like this to ultimately be used as a combination acts_as plugin (acts_as_attachable and acts_as_attachment).

My current schema uses an Attacher model with two polymorphic belongs_to relationships to attempt to accomplish this.

The specific case outlined here involves an Attachable model (Good) and two Attachment models (Image and Movie).

Here is what I have so far:

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

This works insofar as I can do the following:

@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" ...>]

The thrust of my question is: can I use associations to construct the following method/return so I can still do things like @g.attachments.where( ... ):

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

I have tried a bunch of things like this:

good.rb

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

But they tend to throw me this:

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

I think I basically need something that could act like source_type => :any ...

Also, this is my first question on StackOverflow, so please let me know if there is anything I can do to improve my question. Thanks in advance! :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

愿与i 2024-11-10 00:12:55

不幸的是,我得出的结论是,没有一种简单或标准的方法可以做到这一点。我发现的最清晰的基本解决方案来自 Squeegy 对这个问题的回答: Rails 多态多态协会,他将自己的要点引用到一个相当简单的has_relations 模块

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

Unfortunately, I have come to the conclusion that there isn't an easy or standard way to do this. The clearest basic solution I have found is from Squeegy's answer to this question: Rails polymorphic many to many association, where he references his gist to a reasonably simple has_relations module.

I think this basically answers my question and serves a good jumping-off point for creating a more robust solution.

不交电费瞎发啥光 2024-11-10 00:12:55

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

你应该准备好了只需将此行添加到您的 Gemfile:

gem 'kronn-has_many_polymorphs'

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

bundle

sadly this is really not possible with rails, you can try your luck with this extension:
https://github.com/kronn/has_many_polymorphs/tree/

You should be ready to go just by adding this line to your Gemfile:

gem 'kronn-has_many_polymorphs'

and running this command inside your rails application folder:

bundle
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文