2017-10-14 48 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