2013-03-07 2 views
6

Sagen Sie zum Beispiel Ich habe ein Ereignis mit start_date und length (als Ganzzahl für Tage).Schienen & Ransack - Sortierung/Suche basierend auf einer Definition im Modell

Im Modell I end_date als start_date + length.days sehr einfach definieren, wie man es erwarten würde:

def end_date 
    start_date + length.days 
end 

Alle in der Vorlage funktioniert gut, ich event.end_date können das Startdatum angezeigt werden und wurde jedoch viele Tage lang auf , aber, möchte ich jetzt die Ereignisse bis zum Enddatum mit Ransack bestellen.

Die Sortier Link für start_date sieht wie folgt aus: <%= sort_link @q, :start_date, "Start" %>

Wenn ich das gleiche für end_date versuchen (<%= sort_link @q, :end_date, "End" %>) es leider stumm nicht, wie ich es sucht nach end_date als eine Spalte in der Tabelle vermuten und finden es nicht.

Bin ich nur dumm oder versuche ich etwas zu tun, das Ransack einfach nicht gemacht wurde?

+0

sieht aus wie ransack übersetzt Suchparameter in Abfragen auf dem ActiveRecord ORM - die würde definitiv fehlschlagen, es sei denn, Sie haben eine echte Spalte, die die zugrunde liegende DB suchen kann. – bdares

+0

Danke für den Kommentar @bdares. Ich habe es nun geschafft, 'ransacker: end do | r |' im Modell auf folgendes zu setzen: 'Arel :: Nodes :: SqlLiteral.new (" DATE_ADD (events.start_date, INTERVAL events.length DAY) ")'. Wodurch wird die Abfrage erzeugt: 'SELECT DISTINCT events. * FROM Ereignisse ORDER BY DATE_ADD (Ereignisse.start_date, INTERVAL events.length DAY) DESC LIMIT 30 OFFSET 0'. Das funktioniert, fühlt sich aber schrecklich "hacky" an. – bensmithbwd

+0

@bensmithbwd - Es ist schwer, die vollständige Lösung in Ihrem Kommentar zu sehen. Achten Sie darauf, ein vollständiges Beispiel zu schreiben, damit wir die Lösung besser verstehen können. Dann können Sie Ihre eigene Antwort akzeptieren. –

Antwort

10

nur zum Nutzen der alle, um zu sehen, wie ich es tat:

In dem Modell, wo ich end_date definiert

def end_date 
    start_date + length.days 
end 

ich dann eine ‚ranksacker‘ Methode für das hinzugefügt: end_date

ransacker :end_date do |r| 
    Arel::Nodes::SqlLiteral.new("DATE_ADD(`events`.`start_date`, INTERVAL `events`.`length` DAY)") 
end 

Ich weiß ehrlich nicht, ob dies der beste/richtige Weg ist, um die obige Klausel zu machen, aber ich bin viel vertrauter mit SQL als mit Ruby/Rails, also funktionierte es für mich so offen zu sein.

Was das effektiv macht, ist ein Stück von SQL erstellen, die eine Abfrage durch die gleiche Definition wie end_date bestellt (start_date + Länge)

Ich kann jetzt in der Vorlage den folgenden Code für eine Art Link verwenden (was erlaubt Ransacker die ASC/DESC zu handhaben und nicht stören wil_paginate etc etc):

<%= sort_link @q, :end_date, "Event End Date" %>

Wenn Sie auf diesen Link klicken finden Sie eine Abfrage nach dem Vorbild von:

SELECT DISTINCT events.* FROM events ORDER BY DATE_ADD(events.start_date, INTERVAL events.length DAY) DESC LIMIT 30 OFFSET 0 - Alles erstellt und bearbeitet von Ransacker auf einer Spalte in Ihrer Tabelle, die nicht einmal existiert!

Wieder ein kurzer Haftungsausschluss, ich lerne Rails und Ruby seit ungefähr 2 Wochen, komme aus einem Hintergrund von PHP, also bin ich in KEINEM WEG ein Experte und das könnte furchtbar ineffizient sein oder es könnte sehr viel geben besserer "Schienenweg", von dem ich einfach nichts weiß.