如何按相关模型的唯一ID计数

时间:2013-04-23 07:53:21

标签: sql ruby-on-rails

我正在使用Rails 3.1.3和Ruby 1.9.2以及MySQL 5.1进行开发 我想通过独特相关模型的数量来订购模型。 这是我的代码。

class User < ActiveRecord::Base
  has_many :check_ins
  .
  .
end

class CheckIn < ActiveRecord::Base
   belongs_to :user, :counter_cache => true
   belongs_to :ski_resort, :counter_cache => true

   .
   .
end

class SkiResort < ActiveRecord::Base
   has_many :check_ins
   .
   .
end

我想通过办理登机手续的滑雪胜地来订购用户模型。

当用户1在同一个滑雪胜地登记3次时,计数为1 &lt; CheckIn user_id:1,ski_resort_id:1“&gt;
&lt; CheckIn user_id:1,ski_resort_id:1“&gt;
&lt; CheckIn user_id:1,ski_resort_id:1“&gt;

当用户2为不同的滑雪胜地检查4次时,计数为4 &lt; CheckIn user_id:2,ski_resort_id:1“&gt;
&lt; CheckIn user_id:2,ski_resort_id:2“&gt;
&lt; CheckIn user_id:2,ski_resort_id:3“&gt;
&lt; CheckIn user_id:2,ski_resort_id:4“&gt;

我在下面写过,但是按照支票点数排序。

  class User < ActiveRecord::Base
    scope :checked_in_ski_resorts_count_ranking, lambda{
      {
        :joins => {:check_ins => :ski_resort},
        :group => 'users.id',
        :order => 'COUNT(ski_resorts.id) DESC'
      }    
    }
    # => {1 => 3, 2 => 4}
  end

我想要的结果是'{2 =&gt; 4,1 =&gt; 1}”。
如何通过此规则向用户模型添加订单范围?
问候。

2 个答案:

答案 0 :(得分:0)

试试这个:

users = {}
User.all.each do |u|
    users[u] = u.check_ins.uniq.count
end
sorted_users = users.sort_by {|name, check_ins| check_ins}
sorted_users.flatten(1)
(1..sorted_users.count).step(2) do |n|
    sorted_users.delete(n-1)
end

停止编写SQL!

注意:可能不起作用:P

答案 1 :(得分:0)

由于counter_cache根据我所知不支持唯一计数,因此最简单的方法是存储您自己的计数。

ski_resort_checkin_count添加到users作为带default: 0, null: false的整数字段。

class User < ActiveRecord::Base
  has_many :check_ins
  has_many :ski_resorts, through: :check_ins

  def update_counts!
    update_column :ski_resort_checkin_count, ski_resorts.uniq.count
  end
end

class SkiResort < ActiveRecord::Base
  has_many :check_ins
  has_many :users, through: :check_ins
end

class CheckIn < ActiveRecord::Base
  belongs_to :user
  belongs_to :ski_resort

  after_create  :update_counts!
  after_destroy :update_counts!

  def update_counts!
    user.update_counts!
  end
end

然后你可以User.order(:ski_resort_checkin_count)