Rails Active将不同的关联结果记录到一个对象中

时间:2015-08-19 08:48:38

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

我有一个项目模型。 项目模型具有“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

用户有很多项目。

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

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)。但我希望结果(colleagues_of_user)在一个对象(“ActiveRecord :: Relation”)中。

更新:应该注意的另一点是; colleagues_of_user可能是:
 1.任何用户是当前用户的任何项目的成员  2.任何属于当前用户团队项目成员的用户。

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

3 个答案:

答案 0 :(得分:1)

既然你希望fellow_of_user是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

答案 1 :(得分:0)

我认为这样的事情应该有效:

def colleagues
  projects.map(&:all_users)
end

答案 2 :(得分:0)

您也可以尝试加载。

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

由于