我应该放弃多态关联吗?

发布于 2024-11-10 04:01:16 字数 1564 浏览 0 评论 0原文

我的代码仍处于开发阶段,而不是生产阶段,并且我在生成某些视图所需的数据方面遇到了困难。

不想让你们陷入细节,我基本上想浏览多个模型关联以获取每个级别的一些信息。给我带来问题的一个关联是多态的belongs_to。 最相关的关联

Model Post
  belongs_to :subtopic
  has_many :flags, :as => :flaggable

Model Subtopic
  has_many :flags, :as => :flaggable

Model Flag
  belongs_to :flaggable, :polymorphic => true

以下是我想在 Flags#index 视图中显示多个标志的 。我还想显示其他模型的信息,但我在这里省略了具体细节以使其更简单。

在我的 Flags_controller#index 操作中,我当前正在使用 @flags = paginate_by_sql 从数据库中提取我想要的所有内容。我可以成功获取数据,但无法立即加载关联的模型对象(尽管我想要的数据都在内存中)。我现在正在考虑几个选项:

  • 重写我的视图以处理 @flags 对象中的 SQL 数据。这应该可以工作,并且可以防止索引页上每行 5-6 个关联模型 SQL 查询,但看起来很黑客。如果可能的话,我想避免这种情况

  • 简化我的视图并创建额外的页面以获取更详细的信息,仅在查看一个单独的标志时加载

  • 将模型层次结构/定义从多态关联更改为继承。有效地创建一个模块或类 FlaggableObject,它将成为 SubtopicPost 的父级。

我倾向于第三种选择,但我不确定是否能够仅使用 Rails 的 ActiveRecord 帮助程序干净地提取我想要的所有信息。

我想了解这是否可行,更重要的是,如果您有更好的解决方案

编辑:我遇到的一些挑剔的 include 行为

@flags = Flag.find(:all,:conditions=> "flaggable_type = 'Post'", :include => [{:flaggable=>[:user,{:subtopic=>:category}]},:user]).paginate(:page => 1)

=> (valid response)


@flags = Flag.find(:all,:conditions=> ["flaggable_type = 'Post' AND 
  post.subtopic.category_id IN ?", [2,3,4,5]], :include => [{:flaggable=>
  [:user, {:subtopic=>:category}]},:user]).paginate(:page => 1)

=> ActiveRecord::EagerLoadPolymorphicError: Can not eagerly load the polymorphic association :flaggable

My code is still just in development, not production, and I'm hitting a wall with generating data that I want for some views.

Without burying you guys in details, I basically want to navigate through multiple model associations to get some information at each level. The one association giving me problems is a polymorphic belongs_to. Here are the most relevant associations

Model Post
  belongs_to :subtopic
  has_many :flags, :as => :flaggable

Model Subtopic
  has_many :flags, :as => :flaggable

Model Flag
  belongs_to :flaggable, :polymorphic => true

I'd like to display multiple flags in a Flags#index view. There's information from other models that I want to display, as well, but I'm leaving out the specifics here to keep this simpler.

In my Flags_controller#index action, I'm currently using @flags = paginate_by_sql to pull everything I want from the database. I can successfully get the data, but I can't get the associated model objects eager-loaded (though the data I want is all in memory). I'm looking at a few options now:

  • rewrite my views to work on the SQL data in the @flags object. This should work and will prevent the 5-6 association-model-SQL queries per row on the index page, but will look very hackish. I'd like to avoid this if possible

  • simplify my views and create additional pages for the more detailed information, to be loaded only when viewing one individual flag

  • change the model hierarchy/definitions away from polymorphic associations to inheritance. Effectively make a module or class FlaggableObject that would be the parent of both Subtopic and Post.

I'm leaning towards the third option, but I'm not certain that I'll be able to cleanly pull all the information I want using Rails' ActiveRecord helpers only.

I would like insight on whether this would work and, more importantly, if you you have a better solution

EDIT: Some nit-picky include behavior I've encountered

@flags = Flag.find(:all,:conditions=> "flaggable_type = 'Post'", :include => [{:flaggable=>[:user,{:subtopic=>:category}]},:user]).paginate(:page => 1)

=> (valid response)


@flags = Flag.find(:all,:conditions=> ["flaggable_type = 'Post' AND 
  post.subtopic.category_id IN ?", [2,3,4,5]], :include => [{:flaggable=>
  [:user, {:subtopic=>:category}]},:user]).paginate(:page => 1)

=> ActiveRecord::EagerLoadPolymorphicError: Can not eagerly load the polymorphic association :flaggable

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

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

发布评论

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

评论(2

一笔一画续写前缘 2024-11-17 04:01:16

不要放弃多态关联。使用 includes(:association_name) 预先加载关联对象。 paginate_by_sql 不起作用,但 paginate 可以。

@flags = Flag.includes(:flaggable).paginate(:page => 1)

它将使用每个表中的一个查询来完全执行您想要的操作。

请参阅Active Record 关联指南。您可能会看到使用 :include 选项的旧示例,但 includes 方法是 新接口

来自原始海报的更新:

如果您收到此错误:无法立即加载多态关联:flaggable,请尝试如下操作:

Flag.where("flaggable_type = 'Post'").includes([{:flaggable=>[:user, {:subtopic=>:category}]}, :user]).paginate(:page => 1)

请参阅评论以获取更多详细信息。

Don't drop the polymorphic association. Use includes(:association_name) to eager-load the associated objects. paginate_by_sql won't work, but paginate will.

@flags = Flag.includes(:flaggable).paginate(:page => 1)

It will do exactly what you want, using one query from each table.

See A Guide to Active Record Associations. You may see older examples using the :include option, but the includes method is the new interface in Rails 3.0 and 3.1.

Update from original poster:

If you're getting this error: Can not eagerly load the polymorphic association :flaggable, try something like the following:

Flag.where("flaggable_type = 'Post'").includes([{:flaggable=>[:user, {:subtopic=>:category}]}, :user]).paginate(:page => 1)

See comments for more details.

紫轩蝶泪 2024-11-17 04:01:16

问题:对多态关联进行计数。

@flags = Flag.find(:all,:conditions => ["flaggable_type = 'Post' AND post.subtopic.category_id IN ?",
[2,3,4,5]], :include => [{:flaggable => [:user, {:subtopic=>:category}]},:user])
.paginate(:page => 1)

尝试如下:

@flags = Flag.find(:all,:conditions => ["flaggable_type = 'Post' AND post.subtopic.category_id IN ?",
[2,3,4,5]], :include => [{:flaggable => [:user, {:subtopic=>:category}]},:user])
.paginate(:page => 1, :total_entries => Flag.count(:conditions => 
["flaggable_type = 'Post' AND post.subtopic.category_id IN ?", [2,3,4,5]]))

Issues: Count over a polymorphic association.

@flags = Flag.find(:all,:conditions => ["flaggable_type = 'Post' AND post.subtopic.category_id IN ?",
[2,3,4,5]], :include => [{:flaggable => [:user, {:subtopic=>:category}]},:user])
.paginate(:page => 1)

Try like the following:

@flags = Flag.find(:all,:conditions => ["flaggable_type = 'Post' AND post.subtopic.category_id IN ?",
[2,3,4,5]], :include => [{:flaggable => [:user, {:subtopic=>:category}]},:user])
.paginate(:page => 1, :total_entries => Flag.count(:conditions => 
["flaggable_type = 'Post' AND post.subtopic.category_id IN ?", [2,3,4,5]]))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文