有没有办法使用 AREL 进行自定义关联?

发布于 2024-11-03 10:34:18 字数 478 浏览 0 评论 0原文

model Post
  # ActiveRecord associations have tons of options that let
  # you do just about anything like:
  has_many :comments
  has_many :spam_comments, :conditions => ['spammy = ?', true]

  # In Rails 3, named scopes are ultra-elegant, and let you do things like:
  scope :with_comments, joins(:comments)
end

有没有办法使用 AREL 或其他更简洁的语法来像命名范围一样优雅地定义自定义关联?

更新

我认为无论如何将此类细节放入关联中都不是一个好主意,因为关联应该始终/主要定义模型之间的基本关系。

model Post
  # ActiveRecord associations have tons of options that let
  # you do just about anything like:
  has_many :comments
  has_many :spam_comments, :conditions => ['spammy = ?', true]

  # In Rails 3, named scopes are ultra-elegant, and let you do things like:
  scope :with_comments, joins(:comments)
end

Is there any way to use AREL, or an otherwise leaner syntax, to define custom associations as elegantly as named scopes?

update

I've decided it's not a good idea to put that sort of detail into an association anyway, because associations should always/mostly define the basic relationships between models.

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

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

发布评论

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

评论(2

荒人说梦 2024-11-10 10:34:18

解决方案之一是将垃圾邮件范围放在评论上:

model Post
  has_many :comments

  scope :with_comments, joins(:comments)
end

model Comment
  scope :spammy, where(:spammy => true)
end

这在模型责任方面看起来更干净一些。在性能方面,它是完全相同的:

p.comments.spammy.to_sql
# → SELECT "comments".* FROM "comments"
#   WHERE ("comments".post_id = 2) AND ("comments"."spammy" = "t")

额外的好处:您可以从任何其他协会获得垃圾评论。

One of the solutions is to put spammy scope on Comments:

model Post
  has_many :comments

  scope :with_comments, joins(:comments)
end

model Comment
  scope :spammy, where(:spammy => true)
end

This looks a bit cleaner with respect to model responsibilities. Performance-wise it's exactly the same:

p.comments.spammy.to_sql
# → SELECT "comments".* FROM "comments"
#   WHERE ("comments".post_id = 2) AND ("comments"."spammy" = "t")

The added benefit: you can get spammy comments from any other associations.

陌生 2024-11-10 10:34:18

好吧,可能有更好的方法,但我知道您可以使用实际的 Arel 条件(而不是使用 Arel 的 ActiveRecord::Relations) 进行关联href="http://rdoc.info/github/brynary/arel/master/Arel/Nodes/Node#to_sql-instance_method" rel="nofollow">to_sql 功能。

has_many :spam_comments, :class_name => 'Comment', :conditions => Comment.arel_table[:spammy].eq(true).to_sql

您会注意到实际的 Arel 代码并不像 ActiveRecord 关系那样精简。

我确实在以下位置找到了一条评论 Rails master 分支引用了将 Arel 谓词作为条件传递,但该代码似乎不在 3.0 分支中。至少我找不到。

Well, there may be a better way, but I know that you can use actual Arel conditions (as opposed to ActiveRecord::Relations) in associations by using Arel's to_sql feature.

has_many :spam_comments, :class_name => 'Comment', :conditions => Comment.arel_table[:spammy].eq(true).to_sql

You'll notice that actual Arel code isn't as lean as ActiveRecord Relations.

I did find a comment in the Rails master branch that referred to passing an Arel predicate as a condition but that code doesn't seem to be in the 3.0 branch. At least not that I could find.

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