3

我写这个是为了计算唯一用户的回复(对帖子)的数量:

p = Post.find 1
r = p.responses.count(:user_id, distinct: true)

我尝试将其转换为范围,但会引发错误:undefined method 'default_scoped?' for 30:Fixnum

class Response < ActiveRecord::Base
  belongs_to :author, class_name: 'User', foreign_key: 'user_id'
  belongs_to :post

  scope :by_unique_users, joins(:post).count(:user_id, distinct: true)
end

class Post < ActiveRecord::Base
  belongs_to :user
  has_many :responses
end

class User < ActiveRecord::Base
  has_many :posts
  has_many :responses
end
4

1 回答 1

1

来自http://guides.rubyonrails.org/active_record_querying.html#scopes

所有作用域方法都将返回一个 ActiveRecord::Relation 对象,该对象将允许在其上调用更多方法(例如其他作用域)。

换句话说,返回的结果集需要与其他 Active Record 方法调用链接;计算不是可链接的,因此您会得到错误。话虽如此,如果您绝对想使用范围,我们需要使其可链接:

class Response < ActiveRecord::Base
  scope :unique_responses_for_post, lambda {|post_id| where("post_id = ?", post_id).select(:user_id).uniq }
end

您可以根据需要更改名称,我根据它的作用命名它。定义了新范围后,您可以执行以下操作:

p = Post.find 1
r = Responses.unique_responses_for_post(p.id).count()

或者

IMO,这个问题的一个更优雅的解决方案是在你的Post模型中简单地定义一个实例方法:

def distinct_response_count
  responses.count(:user_id, :distinct => true)
end 
于 2012-10-22T15:31:17.230 回答