从组

时间:2017-12-24 15:48:08

标签: ruby-on-rails ruby activerecord

我尝试按oauth_access_tokens对表格(application_id)进行分组,然后从相应的组中按ID选择最高记录(请参阅下面的完整模型)。我已经看过this post,它解释了如何从群组中获取最高ID,但遗憾的是,它不适用于我的案例。

我有一个名为oauth_access_tokens的表,其中包含以下属性:idresource_owner_idapplication_idtokenrefresh_token,{{ 1}},expires_inscopes

我的模型中的方法:

revoked_at

之后调用它:def last_token Doorkeeper::AccessToken.group(:application_id).having('id = MAX(id)') end (我确保数据库中有一些记录存在)。

enter image description here

sql输出:

User.first.last_token

输出: Doorkeeper::AccessToken Load (0.5ms) SELECT `oauth_access_tokens`.* FROM `oauth_access_tokens` GROUP BY `oauth_access_tokens`.`application_id` HAVING id = MAX(id)

为什么我没有获得ID最高的记录?当我运行#<ActiveRecord::Relation []>时,我希望看到User.first.last_token的{​​{1}}为28。

节日快乐!

1 个答案:

答案 0 :(得分:0)

鉴于id:users表的主键,oauth_access_tokens.resource_owner_id指向users.id,这样的事情应该有效:

class User < ApplicationRecord
  ...
  def last_token
    # 'id' (or, self.id) in 'resource_owner_id: id' points to the user id, i.e. 'User.first.id' in 'User.first.last_token'
    Doorkeeper::AccessToken.group(:application_id).where(resource_owner_id: id).pluck('max(id)').first
  end
  ...
end

虽然上述解决方案应该可行,但您可以通过定义相应模型中的关联来改进查询编写方式,如下所示:

class User < ApplicationRecord
  ...
  has_many :access_tokens,
    class_name: 'Doorkeeper::AccessToken',
    foreign_key: :resource_owner_id
  ...
  def last_token
    access_tokens.group(:application_id).pluck('max(id)').first
  end
  ...
end

class Doorkeeper::AccessToken < ApplicationRecord
  ...
  self.table_name = 'oauth_access_tokens'
  belongs_to :resource_owner, class_name: 'User'
  ...
end

在这两种情况下,User.first.last_token都会像您期望的那样返回28

更新

只有1个查询才能获取access_token实例,而不仅仅是ids。该方法现在将返回符合定义标准的ActiveRecord::Relation Doorkeeper::AccessToken个实例。

def last_tokens # pluralized method name
  token_ids = access_tokens.group(:application_id).pluck('max(id)')
  Doorkeeper::AccessToken.where(id: token_ids)
end