2016-04-29 3 views
1

Ich bekomme, dass man nicht die Datenbank in der Ansicht ping ... aber wundern sich über die richtige Lösung. In einer meiner Ansichten, muss ich Informationen über eine @order, es ist Kind items, und auch Amount, ein anderes Modell, basierend auf jedem Kind item. Etwas wie folgt aus:Wie zu vermeiden, schlagen Datenbank in der Ansicht

<% @order.items.each do |item| %> 
    <td><%= item.name %></td> 
    <td><%= Refund.where(item_id:item.id).first.amount %></td> 
    <td><%= Amount.where(item_id: item.id).first.amount %></td> 
<% end %> 

Aus Gründen der Ansicht, die die db Treffer zu vermeiden, ist die einzige Lösung, die ich gedacht habe, ist eine riesige Hash aller relevanten Daten in der Steuerung zu erstellen, die dann zugegriffen wird aus der sicht. So wäre es so etwas wie dieses:

# controller (writing quickly, code may not be totally right, hopefully you get gist 
data = Hash.new 
data["items"] = [] 
@order.items.each do |item| 
    item_hash = { 
    "name" => item.name, 
    "amount" => Amount.where(item_id: item.id).first.amount, 
    "refund" => Refund.where(item_id:item.id).first.amount 
    } 
    data["items"] << item_hash 
end 

# view code 
<% data["items"].each do |item| %> 
    <td><%= item["name"] %></td> 
    <td><%= item["refund"] %></td> 
    <td><%= item["amount"] %></td> 
<% end %> 

Und ich weiß, so dass diese Art von Frage hasst ... aber ich muss wirklich wissen ... ist, dass die beste Lösung? Oder gibt es Best Practices? Der Grund, den ich stelle, ist, weil es in der Ansicht sehr sauber erscheint, aber im Controller sehr sperrig ist, und es wird auch ziemlich unhandlich, wenn Sie eine viel komplexere Menge von geschachtelten Tabellen haben, was ich tatsächlich habe (dh die data Hash wäre ziemlich flippig sein zusammen zu stellen)

+0

Denken Sie daran, '{}' ist so gut wie 'Hash.new' und viel prägnanter. – tadman

+0

Was ist die Verbindung zwischen Artikel, Rückerstattung und Betrag? eins zu eins, eins zu vielen? d.h. Artikel has_one: Rückerstattung? Ihre Frage zeigt an, dass Artikel möglicherweise viele Rückerstattungen hat, aber meine Frage ist, ob dies Ihre Absicht ist? – jverban

Antwort

5

Zunächst ich Assoziationen zwischen Artikel und die 2 anderen Klassen verwenden würde, so dass Sie

item.refund 
item.amount 

Statt Refund.where(...) tun können. Sie könnten weitere Methoden definieren wie

def refund_amount 
    refund.amount 
end 

Und in ähnlicher Weise für die anderen (und hoffentlich mit einem besseren Namen als amount_amount kommen.

Dies hält sowohl Ihre Ansicht und Controller sauber, aber es wird nicht Bis jetzt beinhalten alle Ansätze das Ausführen von 2 Datenbankabfragen pro Element, was für mich das eigentliche Problem ist - ob diese überschüssigen Abfragen in der Ansicht stattfinden oder ob der Controller von geringerer Bedeutung ist.

Jedoch Sie können dies mit dem Include-Mechanismus von Active Record vermeiden:

Die angegebenen Zuordnungen werden in großen Mengen geladen, anstatt sie einzeln nacheinander zu laden, wenn auf die einzelnen Elemente zugegriffen wird.

+0

ja Entschuldigung, ich fragte diese Frage spät in der Nacht, so dass es albern war, sind die Assoziationen an Ort und Stelle, so dass ich nur ein 'item.refund' tun kann. Ich sehe, was Sie sagen, danke für die Erinnerung an die Verwendung von 'include'. Ich werde den Blick nur annähern, danke! – james

Verwandte Themen