2017-03-31 48 views
0

我有一個顯示大量數據的頁面,我正在優化它,並且我努力通過在訂單中獲取正確的數據來平衡減少的DB查詢我需要。Rails 4+,兒童父記錄的訂購清單

Transaction是頂級元素,並且每個transaction具有多個workflows並且每個workflow有許多milestones。我通過position:integer屬性訂購workflowsmilestones

# Top-level element 
class Transaction < ApplicationRecord 
    has_many :workflows 
    has_many :team_members 
end 

# Parent element for milestones 
class Workflow < ApplicationRecord 
    belongs_to :transaction 
    has_many :milestones 
end 

# Unique individual 
class Person < ApplicationRecord 
    has_many :team_members 
end 

# Acts as a join between Transactions and Persons 
class TeamMember < ApplicationRecord 
    belongs_to :transaction 
    belongs_to :person 
    belongs_to :team_member_type 
end 

class TeamMemberType < ApplicationRecord 
    has_many :team_members 
end 

在我的控制器,這是我有:

def show 
    @transaction = Transaction.includes(
    team_members: [:person, :team_member_type], 
    workflows: [:milestones] 
).find(params[id]) 
end 

此收集所有我需要在1所DB查詢的數據,但問題是,當我遍歷里程碑的工作流程,我需要按position屬性對其進行排序。

我可以從數據庫中獲取數據,然後使用Ruby對其進行排序,但這似乎效率低下,我寧願在數據庫中正確完成所有操作(如果可能)。

如果我將其與N+1問題寫的,它應該是這樣的:

<% @workflows.order(:position).each do |workflow| %> 
    <%= workflow.name %> 
    <% workflow.milestones.order(:position).each do |milestone| %> 
    <%= milestone.name %> 
    <% end %> 
<% end %> 

我認爲每個人都同意這是一個壞主意,但我在努力弄清楚如何對數據進行排序並同時優化我的數據庫調用。

我也用team_member_type.value屬性對team_members進行排序,但這與上面的問題相同。

<% @team_members.includes(:team_member_type, :person).order("team_member_types.value").each do |team_member| %> 
    ... 
<% end %> 

我的主要目標是效率。如果我需要使用一些查詢對象來清理它和原始SQL,那我可以,我只是不太熟練SQL,並且如果合理的話,更喜歡使用ActiveRecord。

回答

0

您可以通過在控制器方法這兩個屬性命令:

def show 
    @transaction = Transaction.includes(
    team_members: [:person, :team_member_type], 
    workflows: [:milestones] 
).order('milestones.position, team_member_types.value').find(params[id]) 
end 

讓我知道,如果這有助於。

0

您可以創建包含order_by的關聯,但是我的經驗是,如果在加載時發生沉默失敗,則會導致無序結果。

雖然您認爲,可能是正確的,在Ruby中的排序效率會降低,但我至少會對它進行基準測試。主要的性能問題是在n + 1查詢的情況下,我會樂觀地認爲你會發現Ruby中的排序性能夠高。