5

In my model User, I have scope set up:

scope :count_likes, lambda { 
     select("(SELECT count(*) from another_model) AS count") 
}

If I want to get all attributes of my User + count_likes, I have to do:

Model.count_likes.select("users.*")

because calling select() will the default "*"

I use count_likes scope a lot of my application and my issue is that I have to append select("users.*") everywhere.

I know about the default scope, however, I don't think doing select("users.*") in default scope if a good idea.

Is there a DRY / better way of doing this?

Thanks

4

2 回答 2

4

这真的不是另一个答案。我想对连接发表评论,但评论不能长时间运行,我想提供代码示例。

您需要的是有时获取相关表的所有字段和计数,有时获取不包含 users.* 字段的计数(有时可能只是不包含计数的 user.* 字段)。所以,你将不得不告诉代码你想要哪一个。我认为你正在寻找的是一种例外类型的东西,默认情况下你会得到 user.* 字段和计数,但是当你只想要计数时,指定关闭 select('user.*')。我认为没有这样的解决方案,除非可能使用默认范围。我建议为计数设置一个范围,为用户字段和计数设置一个范围。

这是我要做的:

class Users
  has_many :likes

  def self.with_count_likes
    joins(:likes)
      .select('users.*, count(likes.id) as count')
      .group('users.id')
  end

  def self.count_likes
    joins(:likes)
      .select('users.id, users.username, count(likes.id) as count')
      .group('users.id')
  end
...

当您想要所有用户字段和喜欢计数时,调用 with_count_likes(或将其链接到查询中)。如果您只需要计数和一些识别字段,请调用 count_likes。

我在这里假设,每当您想要计数时,您都希望一些用户字段来识别计数的用途/(谁)。

请注意,某些数据库(如 Oracle)可能需要按“users.*”进行分组。这是 SQL 中的标准,但某些数据库如 mySQL 只使用主键。

于 2015-03-25T14:08:05.127 回答
1

您可以简单地添加users.*到范围。

scope :count_likes, lambda { 
     select("(SELECT count(*) from another_model) AS count, users.*") 
}

高温高压

编辑:我不确定您要达到的目标,但您应该考虑通过joins适当地连接表来使用和获取数据。

编辑:通常我不喜欢做出这样的改变,但情况表明有时我们需要弄脏自己的手。在这种情况下,我会尽量减少进行更改的操作次数。考虑:

scope :count_likes, Proc.new { |all| s = select("(SELECT count(*) from another_model) AS count"); s = s.select("users.*") unless all == false; s}

现在你将users.*无处不在。对于您只需要计数的特定地方,您可以替换它User.count_likes(false),它只会给您计数。因此最小的变化。

可能还有另一种可能,将多个作用域附加在一起,一个用于计数,一个用于users.*并使用它们来达到上述效果。

于 2013-11-14T08:36:14.630 回答