RAILS:如何查询是否已有一个由一组用户组成的团队

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RAILS:如何查询是否已有一个由一组用户组成的团队相关的知识,希望对你有一定的参考价值。

我正在使用rails API,更具体地说是在创建操作中。

我的工作流程是这样的,我有两个rails应用程序,一个是API,另一个是接口。 API管理不同的后端操作,以便处理数据,存储数据,并以json格式响应接口。该接口充当前端,只是向API发出http请求以显示信息。

在我的API中,我有以下3种型号:

class Team < ApplicationRecord
  has_many :team_users
  has_many :users, through: :team_users
end

class User <ApplicationRecord
  has_many :team_users
  has_many :teams, through: :team_users
end

class TeamUser < ApplicationRecord
  belongs_to :user
  belongs_to :team
end

基本上我是从接口向API发送一组用户ID,我想查询是否已经有一个由我传递给API的用户(用户ID)组成的团队。

我已经尝试过这样做:

Team.joins(:team_users).where('team_users.user_id' => [3,5])

此查询的问题在于它返回包含id等于3或5的用户的每个团队。正确的结果是返回一个团队,其中包含用户3和5或5和3作为其团队成员。

提前致谢。

Update

最初的业务规则就是这样,有一个跟踪树木的应用程序,因此我有一个名为树的模型,当我们创建一个树时,必须说明哪个团队创建了这个树。所以我使用了select select用户下拉字段和select2 js库,这就是我将user_ids传递给API的方式。所以基本的想法是检查是否已经是由传递给API的用户组成的团队,如果已经有一个团队我使用它的id并说该树是由该团队注册的,如果没有团队与coposed只买我创建一个新团队的用户,并引用它的ID到树。

答案

您可以通过不同方式解决问题。滚动每个Team记录以检查它是否包含相关的user_ids非常简单但效率低下:

team.user_ids.sort == user_ids.sort

但是我们可以通过逆转过程使其变得高效,即迭代user_ids找出相应的球队,采取他们的Team id的交集,并最终检查是否有任何team_id持有那些user_ids。如果用户已组建团队(user ids),则此行将返回true:

user_ids.map { |id| User.find(id).team_ids }.reduce(:&).present?

您可以将它包含在User类范围中,如下所示:

class User < ApplicationRecord
  ...
  def self.team_exists_for?(user_ids)
    # return early

    # what should it return when user_ids is empty
    # return ??? if user_ids.blank?

    # what should it return when any of the id is absent from :users table
    # set_of_all_user_ids = Set.new(User.pluck(:id))
    # set_of_user_ids     = Set.new(user_ids)
    # return ??? unless set_of_user_ids.subset? set_of_all_user_ids

    # finally
    user_ids.map { |id| User.find(id).team_ids }.reduce(:&).present?
  end
  ...
end

Update

因此,您希望找到仅由user_ids提供的用户的团队,或者与他们一起创建团队并分配回Tree模型实例。结合上述两种方法并在团队模型中定义范围本身似乎是一种更好的解决方案。

class Team < ApplicationRecord
  ...
  def self.find_or_create_for(user_ids)
    # find all team_ids which contain user_ids (inclusive)
    team_ids = user_ids.map { |id| User.find(id).team_ids }.reduce(:&).flatten

    if team_ids.present? # search for the team which ONLY has 'user_ids'
      team_id = team_ids.find { |id| Team.find(id).user_ids.sort == user_ids.sort }
    end

    return Team.find(team_id) if team_id

    # or create a team with user_ids and return
    team = Team.create! # create a team with required attributes
    team.user_ids = user_ids
    team
  end
  ...
end
另一答案

我把它实现为

key: stringTeam模型中添加一个字段Team

class Team < ApplicationRecord
  has_many :team_users
  has_many :users, through: :team_users
  #callback
  before_validation :update_key

  def update_key
    self.key = Team.key_for_users(self.users)
  end

  def self.key_for_users(users)
    users.sort.map(&:id).join("_")
  end
end

所以基本上在这个回调之后,无论何时你创建一个团队,都会有一个密钥,例如: -

users = [3,5]

然后队中的key将是3_5

或用户= [5,3]

然后队中的key将是5_3

从这里我们可以很容易地得到你想要的结果

例如: -

user_ids = [3,5]
[14] pry(main)> user_ids_simple = user_ids.join('_')
=> "3_5"
[15] pry(main)> user_ids_reverse = user_ids.reverse.join('_')
=> "5_3"

和查询将是这样的: -

Team.where("key IN (?)",[user_ids_simple, user_ids_reverse])

它可能对你有所帮助。谢谢

以上是关于RAILS:如何查询是否已有一个由一组用户组成的团队的主要内容,如果未能解决你的问题,请参考以下文章

C++ - 如何有效地找出向量中的任何字符串是不是可以由一组字母组合而成

SwiftUI:如何更新由一组静态数据驱动的列表并从另一组动态数据中提取信息位?

Rails 控制台通过 id 数组查找用户

Rails复杂模型关联,用户和团队之间的共享文档

SQL 由一组 Row 派生值

oracle 事务