Ruby On Rails-User-Modell für mehrere Typen
Ich Lerne RoR aus viele Jahre c# und MSSQL.
Ich habe ein Projekt eine Website zu erstellen für meinen Bruder, der ist ein rental property manager. Ich dachte, dies sollte ziemlich einfach sein, wie die Modelle sollten einfach sein, aber es denke, ich kann über das denken alles oder ich habe Probleme mit dem loslassen von der "alten". Egal, hier ist das problem. Ich bin gestartet mit nur zwei Modellen (Benutzer und Eigentum) . Die Eigenschaft Modell ist einfach, der Benutzer nicht so viel. Ich dachte, wir haben drei Arten von Benutzern in dem system. Mieter, Eigentümer und Verwalter (mein Bruder der nur manager, aber ich dachte, ich würde zu entwerfen, es zu wachsen) Er verwaltet die Eigenschaften für mehrere Besitzer, von denen jeder können, besitzen viele Eigenschaften. Jede Eigenschaft wird ein Eigentümer, ein Mieter und eine Krippe.
Mieter können sich einloggen und sehen nur die Eigenschaft, die Sie mieten, um vielleicht füllen Sie eine IH-Anforderung oder sowas in der Art...(keine wirkliche Anforderung an dieser Stelle auch die Mieter eine Anmeldung zum system, aber ich dachte, es wäre eine gute übung)
Gleiche gilt für Eigentümer, keiner von Ihnen wirklich auf das system zugreifen müssen (Sie mieten mein Bruder, so dass Sie nicht haben, involviert zu sein), aber ich dachte, es könnte nett sein, und mal wieder eine gute übung.
Benutzte ich die Nifty_generator zu generieren, die ein Benutzer, die nur gibt E-Mail, Passwort etc. Ich habe verlängert es sich wie folgt...
class AddProfileDataToUsers < ActiveRecord::Migration
def self.up
add_column :users, :first_name, :string
add_column :users, :last_name, :string
add_column :users, :address1, :string
add_column :users, :address2, :string
add_column :users, :city,:string
add_column :users, :state, :string
add_column :users, :zip, :string
add_column :users, :phone, :string
add_column :users, :email, :string
add_column :users, :user_type, integer
end
def self.down
remove_column :users, :first_name
remove_column :users, :last_name
remove_column :users, :address1
remove_column :users, :address2
remove_column :users, :city
remove_column :users, :state
remove_column :users, :zip
remove_column :users, :phone
remove_column :users, :email
remove_column :users, :user_type
end
end
Hier ist der code, der zum erstellen des Eigenschaften-Tabelle
class CreateProperties < ActiveRecord::Migration
def self.up
create_table :properties do |t|
t.string :address
t.string :city
t.string :type
t.integer :beds
t.float :baths
t.float :price
t.float :deposit
t.string :terms
t.string :laundry
t.datetime :date_available
t.integer :sqft
t.integer :owner_id
t.integer :manager_id
t.integer :tenant_id
t.timestamps
end
end
def self.down
drop_table :properties
end
end
Ich habe Folgendes in der user-Modell, wurde von der nifty_authentication generator
class User < ActiveRecord::Base
#other stuff in the user model up here......
validates_length_of :password, :minimum => 4, :allow_blank => true
#this is the stuff that I have added to the user model
has_many :managed_properties, :class_name => "Property", :foreign_key => "manager_id"
has_many :owned_properties, :class_name => "Property", :foreign_key => "owner_id"
has_one :rented_property, :class_name => "Property", :foreign_key => "tenant_id"
Habe ich dann Hinzugefügt, das zu dem Besitz-Modell....
class Property < ActiveRecord::Base
belongs_to :manager, :class_name => "User" #picked up by the manager_id
belongs_to :owner, :class_name => "User" #picked up by the owner_id
belongs_to :tenant, :class_name => "User" #picked up by the tenant_id
end
Meine Frage ist, wie sieht das aus ... eine akzeptable Art der Modellierung der situation, die ich beschrieben?
Soll ich mich mit der single table inheritance-und die Schaffung eines Mieter-Modell; ein manager-Modell; und eine Eigentümer-Modell? Das problem sah ich mit dabei, dass war, dass ein einzelner Benutzer könnte sowohl ein manager und ein Eigentümer. Dies könnte dadurch gelöst werden, dann mit einem Rollen-Tabellen für den Benutzer, wo ein Benutzer hat viele Rollen und eine Rolle hat viele Benutzer. Hatte ich auch angeschaut, Profil-Tabelle mit eins-zu-eins übereinstimmung mit der Tabelle user und diese polymorphe aber ich glaube nicht, dass diese situation wirklich fordert und es nicht die Frage zu lösen, wo ein Benutzer kann ein Eigentümer und manager.....
Dies ist, wenn ich begann zu denken, dass vielleicht ich war über das denken das problem und kam mit dem, was Sie hier sehen.
Ich begrüße jeden konstruktiven Kommentare, die Sie haben können. Bitte beachten Sie, dass ich nie wirklich gebaut, alles in Rails und all das ist ein Erster Versuch, vor einer Woche hatte ich noch nie installiert, die Schienen auf meinem computer.
Ich weiß nicht, ob das zählt, aber ich dachte mir, dass der admin /manager, verantwortlich für das anlegen von Benutzern. Ist das nicht ein self-sign-up Art von Website. Der manager wird neuer Besitzer, wenn er sich anmeldet neue Besitzer, und die gleichen gehen für die Mieter. Dadurch wird es einfacher, um zu bestimmen, die Art der Benutzer-er ist zu schaffen.
Vielen Dank für jede Einsicht, die Sie haben können.
Du musst angemeldet sein, um einen Kommentar abzugeben.
FWIW, das sieht fein zu mich. Ich könnte schauen, declarative_authorization zur Verwaltung Ihrer Rollen, die am Ende vielleicht etwas umständlich, vor allem vom UI-Standpunkt. Verwaltung der Benutzer mit mehreren Rollen scheint eher geeignet als STI in dieser situation, weil, wie Sie sagen, ein Benutzer kann sowohl manager und Mieter, etc.
Einen Ansatz zu halten, den code für manager, Mieter und Eigentümer getrennt, während es für die Verwendung von allen drei Rollen in einer einzigen Instanz sein könnte, um dynamisch Module darstellen die Rollen basierend auf dem, was Rollen, die ein Benutzer hat. Sie hätten immer noch eine Basis-Klasse der Benutzer, aber statt mit STI, die würde, beschränken Sie zu einem einzigen Vererbung Struktur, Sie könnten mix-in-Module auf der Grundlage der Rollen, die jeder Benutzer hat, die vielleicht einfach pivot auf welche Eigenschaften belong_to einem bestimmten Benutzer während der Initialisierung.
Für diese könnte ich erstellen Sie eine Benutzer-Fabrik, die Sie besichtigen können die Benutzer für die verschiedenen Rollen, die Sie spielt und verlängern die singleton-Klasse, dass der Benutzer mit dem entsprechenden Modul: erweitern Sie zusammen mit dem Mieter-Modul für Anwender, die Mieter haben Eigenschaften, die Erweiterung der Manager-Modul für Benutzer, die verwalteten Eigenschaften, etc.
Aus der Sicht der declarative_authorization, Sie könnte erklären Sie die role_symbols ähnlich abhängig, ob Verbände wie managed_properties besiedelt wurden, zum Beispiel:
Oder etwas ähnliches. Sie würde wahrscheinlich wollen, legen Sie die Rollen UND schließen Sie die entsprechenden module an der gleichen Zeit. Ruby und Rails bietet viele Möglichkeiten, über metaprogramming-Techniken dynamisch dekorieren Sie mit der Funktionalität der einzelnen Modelle. Mein Ansatz, der möglicherweise oder möglicherweise nicht für Ihre Anwendung geeignet, aber es gibt unzählige andere Möglichkeiten, wie Sie nähern konnten das problem und halten Sie Ihren code sauber und TROCKEN.
Insgesamt scheint es mir deine Daten Modell solide ist, und Ihr Instinkt nicht zu verwenden STI zu verwalten mehrere Rollen, ist richtig. Es sieht nicht zu mir, wie Sie schon overthought es -- ich denke, du bist auf dem richtigen Weg. Es ist eigentlich ziemlich Rails-y für einen ersten Durchlauf.
EDIT: weißt Du, je mehr ich darüber nachdenke, bin ich mir nicht sicher, was der Vorteil von halten die manager - /Mieter - /Eigentümer-Funktionalität in separate Module wirklich ist. In meinem früheren Inkarnation als Java - /C# - Typen, die ich hätte alles über die SRP/IOC und totale Trennung von Bedenken. Aber in Ruby und Rails ist es bei weitem nicht so große einen deal, da es dynamisch typisiert und die Kupplung ist nicht annähernd so groß, oder zumindest die gleiche Art von Sorge, dass es in der statisch typisierten Umgebungen. Sie könnten völlig in Ordnung, nur alles von der einzelnen Rolle die Funktionalität in den single-User-Modell und keine Sorge mit den Modulen, zumindest noch nicht.
Ich bin auf dem Zaun hier, und würde es begrüßen, input von anderen. Für mich einer der Vorteile von Ruby-Klassen, im Gegensatz zu Java-Klassen/Pakete oder .NET-Klassen/Baugruppen, ist, dass man Sie immer umgestalten, wie Sie es brauchen und nicht annähernd so besorgt über die Klassen -, package -, namespace -, dll-oder jar gekoppelt ist, um ein anderes, etc. Ich sage nicht, dass SRP nicht wichtig ist, in Ruby überhaupt nicht. Aber ich bin nicht annähernd so paranoid wie ich verwendet zu werden.
EDIT: Paul Russell ist ein ausgezeichneter Punkt. Ich denke, Sie sollten ernsthaft in Erwägung ziehen, dass mehrere Mieter/Verwalter/Vermieter pro Grundstück. In Rails das könnte ausgedrückt werden durch eine relationale Tabelle und eine has_many :through association, plus STI zu beschreiben, die verschiedenen Arten von Beziehungen. Ich denke auch, dass es notwendig sein wird, zum invertieren der Beziehung zwischen dem Nutzer (als Mieter) und der Eigenschaft. Eine Eigenschaft kann mehr als ein Mieter, aber ein Mieter kann nicht Leben mehr als eine Eigenschaft. (oder vielleicht kann Sie? Scheint nicht rechts, aber...)
Vielleicht so etwas wie (das ist sehr quick and dirty, so verzeihen Sie etwaige fehlende details bitte):
Wie gesagt, das ist quick and dirty, ein high-level-first-pass. Beachten Sie, dass wir jetzt schon erstellt Managership und Eigentum-Rollen, die enthalten kann, die Manager und Eigentümer-spezifische Funktionen, die Beseitigung der ehemaligen dilemma, ob zu silo, daß die Funktionalität in separate Module.
** Beachten Sie auch, dass habe ich invertiert der Mieter/Objekt-Rolle -- ich denke, dies war eine notwendige änderung, die an Ihre domain. Offensichtlich ein Wohnsitz kann mehr als ein Mieter. Es scheint mir (im moment), dass Sie zu halten kann der Mieter-spezifische Funktionen auf die User-Modell.
Was bedeutet der Streik ist mir, dass Ihre aktuelle Modell verbietet, dass mehrere Mieter oder Vermieter auf eine bestimmte Eigenschaft, und setzt Voraus, dass diese Beziehungen dauerhaft sind.
In England wenigstens, es ist sehr üblich, um die Lage einer Immobilie ist im Besitz eines Ehepaares, und konnte deshalb mehrere Vermieter (meine Frau und ich sind in dieser position, zum Beispiel). Ebenso, für bestimmte Arten von lassen, es ist sehr üblich, denn es werden mehrere Mandanten in einer einzelnen Eigenschaft.
Wenn Sie denken, ich bin hier richtig, ist es eine überlegung Wert die Einführung einer user_property_role' Modell-Objekt zwischen dem Benutzer und der Eigenschaft. Sie würden dann eine has_many-Beziehung sowohl aus Benutzer und das Eigentum an user_property_role. Wenn diese Rolle hatte eine "relationship type" Feld können Sie einstellen, um z.B. 'Vermieter', Sie könnte dann mit has_many :through und scopes (auf der user_property_role) - Objekt zu tun, z.B. Immobilien.Benutzer.Vermieter oder Eigenschaft.Benutzer.Mieter.
Unter diesem Ansatz würde es auch erlauben, die Sie tun, um Dinge wie diese Beziehungen 'begin' und 'end' - Daten, die Aufzeichnung der Tatsache, dass eine Eigenschaft mehrere Mieter im Laufe der Zeit, zum Beispiel, oder dass eine Eigenschaft verwaltet werden, die von verschiedenen Personen im Laufe der Zeit. Wieder, sollten Sie in der Lage zu bauen, diese in eine Reihe von scopes, so dass Sie tun können, z.B. Immobilien.Benutzer.aktuelle.Mieter oder sogar user.Eigenschaften.aktuelle.Mieter.
Hoffe, das hilft, und nicht nur hinzufügen, um Ihre Verwirrung!!
def self.managed where(:type == "Ownership") end
in der Rolle Modell scheint nicht zu funktionieren! Ich kann nicht call user.Konten.verwaltet seit gelungen ist, in die Rolle Modell, nicht das Konto Modell!