Wie man immer einen Wert für Konto-scope in Rails gesetzt?
-
16-09-2019 - |
Frage
ich auf einem Multi-User gerade arbeitete, Multi-Account-App wobei 1-Konto kann n Benutzer hat. Es ist sehr wichtig, dass jeder Benutzer nur Informationen von seinem Konto zugreifen kann. Mein Ansatz ist es, ein account_id zu jedem Modell in der DB zu addieren und als einen Filter in jedem zu Controller hinzufügen nur Objekte mit dem aktuellen account_id zu wählen. Ich werde die Genehmigung Plugin verwenden.
Dieser Ansatz ist eine gute Idee?
Was ist der beste Weg, um immer die account_id für jedes Objekt festlegen, ohne das Schreiben
erstellt wirdobject.account = @current_account
in jedem CREATE-Aktion? Vielleicht ein Filter?
Auch ich bin über die beste Art und Weise nicht sicher, ob die Filter für die Auswahl von Optionen zu implementieren. Ich brauche so etwas wie ein allgemeiner Zustand. Egal, was sonst in der SQL-Anweisung angezeigt wird, gibt es immer ein „WHERE account_id = XY“
Vielen Dank für Ihre Hilfe!
Lösung
Dies ist ähnlich wie bei einem User.has_many: E-Mails Szenario. Sie haben nicht den Benutzer möchten, dass andere Völker E-Mails sehen, indem Sie die ID in der URL zu ändern, so können Sie dies tun:
@emails = current_user.emails
In Ihrem Fall, können Sie wahrscheinlich etwas tun:
class ApplicationController < ActionController::Base
def current_account
@current_account ||= current_user && current_user.account
end
end
# In an imagined ProjectsController
@projects = current_account.projects
@project = current_account.projects.find(params[:id])
Andere Tipps
Ich weiß, ich weiß, wenn Sie Session-Variablen oder Instanzvariablen in Ihrem Modell zugreifen Sie nicht das MVC-Muster verstanden haben und „sollte auf PHP zurückgehen“. Aber noch, könnte dies sehr nützlich sein, wenn man - wie wir - viele Controller und Aktionen, wo man nicht immer will @ current_account.object.do_something schreiben (nicht sehr DRY)
.Die Lösung, die ich gefunden ist sehr einfach:
Schritt 1: Fügen Sie Ihre current_account zu Thread.current, so zum Beispiel
class ApplicationController < ActionController::Base
before_filter :get_current_account
protected
def get_current_account
# somehow get the current account, depends on your approach
Thread.current[:account] = @account
end
end
Schritt 2: Fügen Sie ein current_account Methode auf alle Ihre Modelle
#/lib/ar_current_account.rb
ActiveRecord::Base.class_eval do
def self.current_account
Thread.current[:account]
end
end
Schritt 3: Voilà, in Ihrer Models Sie etwas tun können:
class MyModel < ActiveRecord::Base
belongs_to :account
# Set the default values
def initialize(params = nil)
super
self.account_id ||= current_account.id
end
end
Sie können auch mit so etwas wie die before_validation Rückruf in active_record und dann machen mit einer Bestätigung, dass das Konto ist immer gesetzt.
funktionieren könnteDer gleiche Ansatz verwendet werden könnte, wenn man immer die current_user zu jedem erstellten Objekt hinzufügen möchten.
Was denken Sie?
Ihre zweite Frage zu beantworten, überprüft die neue default_scope
Feature in Rails 2.3.
Ich verstehe, dass Sie nicht wollen, über Scoping Sie berücksichtigen alle Zeit zu stören. Um ehrlich zu sein, es ist ein Schmerz in den a **.
ein wenig Magie hinzuzufügen und haben dies getan Scoping nahtlos einen Blick auf die folgenden gem geben
http://gemcutter.org/gems/account_scopper
Hope, das hilft,
- Sébastien Grosjean - ZenCocoon