Ich arbeite an einer Rails-App (derzeit 2.3.4), die Subdomänen verwendet, um unabhängige Account-Sites zu isolieren. Um klar zu sein, was ich meine, ist foo.mysite.com sollte den Inhalt des foo-Accounts anzeigen und bar.mysite.com sollte den Inhalt des Balkens anzeigen.
Wie stellen Sie am besten sicher, dass alle Modellabfragen auf die aktuelle Subdomäne beschränkt sind?
Einer meiner Controller sieht beispielsweise so aus:
%Vor% (Hinweis @global_organization
wird im application_controller über subdomain-fu gesetzt.)
Wenn das, was ich bevorzugen würde, ist etwas wie:
Wo das Seitenmodell findet, wird automatisch auf die richtige Organisation beschränkt. Ich habe versucht, die default_scope-Direktive wie folgt zu verwenden: (im Page-Modell)
%Vor%(Nochmal, um zu bemerken, derselbe application_controller setzt Thread.current [: organisation] auf die Organisations-ID für den globalen Zugriff.) Das Problem bei diesem Ansatz ist, dass der Standardbereich bei der ersten Anfrage gesetzt wird und niemals verändert wird nachfolgende Anfragen an verschiedene Subdomains.
Bisher drei scheinbare Lösungen:
1 Verwenden Sie separate vhosts für jede Subdomain und führen Sie einfach verschiedene Instanzen der App pro Subdomain aus (mit mod_rails). Dieser Ansatz ist für diese App nicht skalierbar.
2 Verwenden Sie den obigen Ansatz des ursprünglichen Controllers. Leider gibt es eine ganze Reihe von Modellen in der App und viele der Modelle sind ein paar Joins aus der Organisation entfernt, so dass diese Notation schnell umständlich wird. Was noch schlimmer ist, ist, dass Entwickler aktiv dazu aufgefordert werden, sich an die Einschränkungen zu erinnern und diese anzuwenden oder ein signifikantes Sicherheitsproblem zu riskieren.
3 Verwenden Sie einen before_filter, um den Standardbereich der Modelle bei jeder Anforderung zurückzusetzen. Ich bin mir nicht sicher, welche Leistung hier erzielt wird oder wie Sie am besten auswählen können, welche Modelle per Update aktualisiert werden sollen.
Gedanken? Irgendwelche anderen Lösungen, die ich vermisse? Dies scheint ein allgemein genug Problem zu sein, dass es eine Best Practice geben muss. Alle Eingaben geschätzt, danke!
Seien Sie vorsichtig, wenn Sie hier den Standardbereich verwenden, da Sie dadurch vor allem beim Erstellen von Datensätzen in ein falsches Sicherheitsgefühl geraten.
Ich habe dein erstes Beispiel immer benutzt, um das klar zu halten:
%Vor%Der Hauptgrund ist, dass Sie auch sicherstellen möchten, dass diese Zuordnung auf neue Datensätze angewendet wird. Ihre neuen / create-Aktionen sehen dann wie folgt aus und stellen sicher, dass sie ordnungsgemäß auf die übergeordnete Zuordnung beschränkt sind:
%Vor% Haben Sie versucht, default_scope
a lambda
zu definieren? Das lambda
-Bit, das die Optionen definiert, wird jedes Mal ausgewertet, wenn der Bereich verwendet wird.
Es macht im Wesentlichen Ihre dritte Option, indem Sie mit Ihrer vorherigen Filterzauberei zusammenarbeiten. Aber es ist ein wenig aggressiver als das, jeden einzelnen Fund, der auf dem Page-Modell verwendet wird, anzugreifen.
Wenn Sie dieses Verhalten für alle Modelle haben möchten, können Sie das default_scope zu ActiveRecord :: Base hinzufügen, aber Sie erwähnen einige, die ein paar Joins entfernt sind. Wenn Sie also diesen Weg gehen, müssen Sie die Standardbereiche in diesen Modellen überschreiben, um die Joins zu adressieren.
Sie sollten besser eine Datenbank pro Konto haben und die Datenbankverbindung wechseln basierend auf der Subdomain.
Zusätzlich zu dem obigen Link, wenn Sie ein Modell haben (in Ihrem Fall Konto), dass Sie die Standarddatenbank verwenden möchten, fügen Sie einfach establish connection
in das Modell ein.
Tags und Links ruby-on-rails