【问题标题】:Rails Active Record different association results into one objectRails Active Record 不同的关联结果到一个对象中
【发布时间】:2023-03-27 20:55:01
【问题描述】:

我有一个项目模型。 项目模型有“all_users”实例方法,它返回项目的所有用户。

class Project < ActiveRecord::Base
    has_many :memberships
    has_many :users, through: :memberships, source: :member, source_type: 'User'
    has_many :teams, through: :memberships, source: :member, source_type: 'Team'

    scope :all_users, -> (project) {
        User.where(%{
            (users.id in (select member_id from memberships where project_id = #{project.id} and member_type = 'User')) OR
            (users.id in (select user_id from teams_users where team_id IN (select member_id from memberships where project_id = #{project.id} and member_type = 'Team')))
            })
    }

    def all_users
        Project.all_users(self).order(:name)
    end
end

一个用户有很多项目。

我想在用户模型中创建一个实例方法来返回实例的所有项目的所有用户。如:

class User < ActiveRecord::Base
    has_many :memberships, as: :member, dependent: :destroy
    has_many :projects, through: :memberships

    def colleagues
        colleagues_of_user = []
        projects.each do |project|
            project.all_users.each do |user|
                colleagues_of_user << user
            end
        end
        teams.each do |team|
            team.projects.each do |project|
                project.all_users.each do |user|
                    colleagues_of_user << user
                end
            end
        end
        colleagues_of_user.uniq
    end
end

问题是;我想将所有“project.all_users”连接到一个对象中,但我不能。我必须把它们变成一个数组(to_a)。但我想要一个对象(“ActiveRecord::Relation”)中的结果(colleagues_of_user)。


UPDATE:还有一点需要注意的是; 同事的用户可能是:
1. 属于当前用户的任何项目的任何用户。
2. 作为当前用户团队项目成员的任何用户。

我已经更新了关于这些笔记的“同事”方法。如何将所有结果放入一个 ActiveRecord::Relation 对象? (不是数组)

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 rails-activerecord


    【解决方案1】:

    由于您希望同事们的用户成为 ActiveRecord::Relation 而不是数组,我认为您可以这样做:

    def colleagues
      colleague_ids = projects_colleague_ids + teams_projects_colleague_ids
      colleagues_of_user = User.where(id: colleague_ids.flatten.uniq )
    end
    
    private
    
    def projects_colleague_ids(projects = nil)
      projects ||= self.projects
      projects.includes(:users).collect{ |project| project.all_users.pluck(:id) }.flatten.uniq
    end
    
    def teams_projects_colleague_ids
      teams.includes(projects: :users).collect do |team|
        projects_colleague_ids( team.projects )
      end.flatten.uniq
    end
    

    【讨论】:

      【解决方案2】:

      我认为这样的事情应该可行:

      def colleagues
        projects.map(&:all_users)
      end
      

      【讨论】:

        【解决方案3】:

        您也可以尝试使用急切加载。

        Project.includes(users).map(&:all_users)
        

        谢谢

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-12-25
          • 2017-10-14
          • 2014-12-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多