2017-11-17 4 views
0

alle!Erhalten Sie alle Konfliktdaten in einer Schienenabfrage

Ich erstelle eine Rails-App, um Urlaub in einer Regierungsinstitution zu verwalten und zu planen.

Das System muss die Ferien filtern und sie in ein Gitter laden (sehen Sie das Gitter im Anschluss unten, auf Portugiesisch, Entschuldigung dafür).

Das Problem ist: Ich muss alle Ferien, die in Konflikt sind, filtern.

Beispiel: (MM-TT-JJJJ)

Johns Urlaub: beginnt in 2018.01.01, endet 2018.01.15. Maries Urlaub beginnt am 01-01-2018, endet am 01-10-2018.

Johns Urlaub und Maries Urlaub sind in Konflikt.

Eine Person kann Ihren Urlaub durch das Jahr teilen.

Wie kann ich eine Rails-Abfrage schreiben, um alle Ferien zu bekommen, die in Konflikt sind?

Ferien Schema:

t.integer "fs_manager_id", limit: 19, precision: 19 
t.integer "year", precision: 38 
t.date "date_ini" 
t.date "date_end" 
t.integer "days", precision: 38 
t.boolean "approved", default: false 
t.datetime "date_approved", precision: 6 
t.datetime "created_at", precision: 6, null: false 
t.datetime "updated_at", precision: 6, null: false 
t.integer "fs_balance_id", precision: 38 
t.integer "fs_person_id", precision: 38 
t.index ["fs_balance_id"], name: "i_fs_vacations_fs_balance_id" 
t.index ["fs_manager_id"], name: "i_fs_vacations_fs_manager_id" 
t.index ["fs_person_id"], name: "i_fs_vacations_fs_person_id" 

Image: Grid with all vacations and vacation's owner dd/MM/yyyy

EDIT: Das Problem ist: Ich habe alle Urlaub zu filtern, die in Konflikt stehen und ihnen Benutzer zu zeigen.

+0

ich es nicht glaube, zeigen eine Abfrage ist das genau das tut, was Sie wollen. Ich würde anfangen, indem ich alle Daten gruppiere und dann, welche Gruppe der Daten mehr als 1 Wert hat, würde ich annehmen, dass sie sich schneiden. – Vlad

+0

Welche Datenbank verwenden Sie? –

+0

@MichailKatrin, Oracle! –

Antwort

0

Folgendes können Sie dies in ActiveRecord Version 5 oder höher tun, zerlegt und in ein paar Brocken zusammengebaut. Sie müssen vacations sich verbinden, die ich mit dem Alias ​​conflicts getan haben:

# Match only on differing ids because each vacation will conflict with itself in the result 
conflict_join = Vacation.joins("LEFT JOIN vacations AS conflicts ON conflicts.id != vacations.id") 

conflict_by_start_date = conflict_join.where("conflicts.start_date >= vacations.start_date AND conflicts.start_date <= vacations.end_date") 
conflict_by_end_date = conflict_join.where("conflicts.end_date >= vacataions.start_date AND conflicts.end_date <= vacations.end_date") 

# Can only use the .or function in ActiveRecord 5 or above 
conflicts = conflict_by_start_date.or(conflict_by_end_date) 

Das Ergebnis all vacations sein wird, die eine andere widersprüchliche Urlaub. Wenn Urlaub A mit Urlaub B in Konflikt steht, werden A und B in die Ergebnisse einbezogen. Im Fall von mehreren Konflikten, wie A Konflikte mit B und Konflikte mit C, würde A mehrmals erscheinen, so dass Sie das vielleicht irgendwie behandeln möchten.

Diese Abfrage auch ein Ergebnis erhalten verwendet werden könnten, die die spezifischen Urlaubs Konflikt miteinander über ein select wie conflicts.select("vacations.id AS vacation_id, conflicts.id AS conflicting_vacation_id")

+0

Ich werde es definitiv versuchen! Super Trick! Danke vielmals! –

0

Es ist schwer zu sagen, wie diese Abfrage mit Active

Aber Sie können eine Monster einfache SQL-Abfrage machen schreiben:

query = 'select distinct a1.* 
    from vacations as a1, vacations as a2 
    where a1.start_date < a2.end_date and 
    a1.end_date > a2.start_date and 
    a1.id <> a2.id' 
response = ApplicationRecord.connection.execute(query) 

Und dann analysieren manuell einen reponse mit map oder etwas Derartiges .

+0

Ich habe so etwas versucht, aber das Wartbare war ein Durcheinander, aber kann funktionieren, wenn es vorsichtig verwendet wird. Danke vielmals. –

Verwandte Themen