2017-03-31 2 views
0

Ich habe eine Seite, die eine Menge Daten anzeigt, und ich arbeite daran, es zu optimieren und ich habe Probleme mit dem Ausgleich von DB-Abfragen mit den richtigen Daten in der Reihenfolge Ich brauche.Rails 4+, Bestellliste der Eltern Datensätze von Kindern

A Transaction ist das Top-Level-Element, und jedes hat mehrere transactionworkflows und jede workflow viele milestones hat. Ich bestelle die workflows und milestones durch ein position:integer Attribut.

# 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 

In meinem Controller ist es das, was ich habe:

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

Dieser sammelt alle Daten, die ich in 1 DB Abfrage benötigen, aber das Problem ist, wenn ich über die Meilensteine ​​für einen Workflow durchlaufen, ich muss nach dem Attribut position sortiert werden.

Ich kann die Daten aus der DB greifen und dann mit Ruby sortieren, aber das scheint ineffizient und ich würde es vorziehen, alles in der DB richtig zu machen (wenn möglich).

Wenn ich es mit einem N+1 Ausgabe zu schreiben, würde es so aussehen:

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

Ich denke, alle sind sich einig, dass eine schlechte Idee, aber ich bin zu kämpfen, um herauszufinden, wie die Daten zu sortieren und gleichzeitig meine DB-Aufrufe optimieren.

Ich sortiere auch die team_members durch die team_member_type.value Attribut, aber das ist die gleiche Frage wie oben.

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

Mein Hauptziel ist Effizienz. Wenn ich einige Query-Objekte verwenden muss, um es zu bereinigen und Raw-SQL, bin ich damit einverstanden, ich bin nur nicht sehr kompetent in SQL und würde es vorziehen, ActiveRecord zu verwenden, wenn es sinnvoll ist.

Antwort

0

Sie können durch diese beiden Attribute in der Controller-Methode bestellen:

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

Lassen Sie mich wissen, ob das hilft.

0

Sie könnten Assoziationen erstellen, die order_by enthalten, aber ich habe die Erfahrung gemacht, dass beim Hinzufügen von E-Mails automatisch ein Fehler auftreten kann, sodass Sie ein ungeordnetes Ergebnis erhalten.

Obwohl Sie wahrscheinlich richtig glauben, dass das Ordnen in Ruby weniger effizient wäre, würde ich es zumindest benchmarken. Das Hauptleistungsproblem liegt in der n + 1-Abfragesituation, und ich wäre optimistisch, dass Sie die Sortierung in Ruby als ausreichend leistungsfähig finden.

Verwandte Themen