如何在Rails中执行此PG查询?

时间:2016-09-04 15:22:50

标签: ruby-on-rails ruby postgresql activerecord ruby-on-rails-5

我有以下简单的关系:

class Company
  has_many :users
end

class User
  belongs_to :company
  has_and_belongs_to_many :roles
end

class Role
  has_and_belongs_to_many :users
end

唯一重要的一栏是:name上的Role

我正在尝试制作一个有效的PostgreSQL查询,该查询将为每个用户显示所有role_names的逗号分隔列表。

到目前为止,我已经实现了这一点,如果只分配了一个角色,那么效果很好。如果我添加另一个角色,我会得到重复的用户。我试图通过使用role_names functionstring_agg()字段中返回以逗号分隔的列表,而不是尝试解析它。

到目前为止,这是我的查询,我有点未能完成最后一步。

User.where(company_id: id)                             
  .joins(:roles)                                       
  .select('distinct users.*, roles.name as role_name') 

修改

我可以通过原始SQL(粗略)让它工作但是当我把它放在ActiveRecord格式时,rails不知道如何理解它

ActiveRecord::Base.connection.execute('SELECT users.*, string_agg("roles"."name", \',\') as roles FROM "users" INNER JOIN "roles_users" ON "roles_users"."user_id" = "users"."id" INNER JOIN "roles" ON "roles"."id" = "roles_users"."role_id" WHERE "users"."company_id" = 1 GROUP BY users.id')

User.where(company_id: id)
  .joins(:roles)
  .select('users.*, string_agg("roles"."name" \',\')')
  .group('users.id')

1 个答案:

答案 0 :(得分:0)

在我看来你想做:

User.roles.map(&:name).join(',')

(在我的opionion中,SQL是使用数据库时更好的选择,但是当你处于轨道上时,你应该尽可能多地使用Active Record。请注意性能问题!)