2017-10-14 33 views
0

我有3级关系。Rails - 在视图(或助手)中采集子记录的名称

用户的has_many客户HAS_MANY项目

User.projects将工作User.clients会工作。

在视图中,我试图弄清用户拥有的每个客户端的项目。

IE客户端A有2个项目,客户端B有4个,客户端C有3个。它会返回“客户端A:2.客户端B:4.客户端C 3”。

目前我能得到的最接近的是pie_chart current_user.projects.group(:client).count,它实际上只是沿着#<Client:0x000000xd3948>这条线返回 - 我假设的模型/关系。

我尝试做current_user.clients,所有记录将返回undefined

我在想也许我需要把这个变成一个帮手,并迭代user.clients并计算出来,但是考虑到这种关系似乎是错误的。

(不确定要添加哪些其他输入)

基本上我需要一个Group By但挣扎的Rails-ING它。

SELECT clients.name, count(*) FROM clients JOIN projects on clients.id = projects.client_id WHERE user_id = 1 GROUP BY clients.name;

该查询返回我需要确切的结果。

回答

0

为了解决这个问题,我结束了使用ERB-> JavaScript的过程。

1)我创建了一个帮助器来生成数组。谷歌图表想要的格式为[名称,计数]

module ProjectsHelper 
    def get_projects_per_client(user) 
     custom_arr = [] 
     custom_arr << ['Client', 'Projects per Client'] 
     user.clients.each do |p| 
      custom_arr << [p.name, p.projects.count] 
     end 
     return custom_arr 
    end 
end 

我强迫前缀我所需要的标题,然后使用JavaScript的内一个非常简单的调用 - var client_arr = <%= raw get_projects_per_client(current_user) %>

原始的目的是远程符号/报价替换。其他方面你的字符串变成&quot;,并打破JavaScript。

不确定这是否正确,但我喜欢它的影响。

+0

试试这个'custom_arr = user.clients.collect {| p | [p.name,p.projects.count]}' –

+0

@StephenM比我的更干净 - 谢谢!我会研究'collect'。 – DNorthrup

0

你可以做所有的,在这样一个查询:

user.projects 
    .select("projects.name, COUNT(clients.id) AS clients_count") 
    .left_joins(:clients) 
    .group(:id) 
    .map { |project| [project.name, project.clients_count] } 

你也可以为您的项目添加计数器缓存 - >这样的客户的关系:

迁移:

class AddClientCounterCacheToProjects < ActiveRecord::Migration 
    def change 
    add_column :projects, :clients_count, :integer, default: 0, null: false 
    end 
end 

客户端模式:

class Client < ApplicationRecord 
    belongs_to :project, counter_cache: true 
end 

然后你可以看一下客户的计数的项目,而不做N + 1这样的:

project.clients.size 

它导入您使用.size,而不是.count,因为.count将始终对数据库执行另一个查询。然后

这将结束这样看:用这样的代码project.clients.any?project.clients.empty?等时

user.projects.map { |project| [project.name, project.clients.size] } 

计数器缓存也节约了资源。

如果你要计算的用户客户端,您可以在用户模型中添加has many through关系是这样的:

class User < ApplicationRecord 
    has_many :projects 
    has_many :clients, through: :projects 
end 

然后你就可以得到客户数是这样的:

user.clients.size