Add polymorphic properties to User
authorJessica Tallon <tsyesika@tsyesika.se>
Fri, 17 Jul 2015 15:49:18 +0000 (17:49 +0200)
committerJessica Tallon <tsyesika@tsyesika.se>
Fri, 31 Jul 2015 13:14:41 +0000 (15:14 +0200)
This adds the ability to search for any user based on the generic
User case and be given back the specific LocalUser or RemoteUser.

This will require any code using the model to look which attributes
they are searching on and specify the specific User model they are
on if they're not on the generic User model. This will also require
new users to be created with LocalUser.

mediagoblin/db/migrations.py
mediagoblin/db/models.py

index 02dc996c42fb5a4021a5da98bd5d97d67b7a039b..6b25aebf89e517725d12310d86e6613aae7e1317 100644 (file)
@@ -1460,15 +1460,15 @@ def federation_user_create_tables(db):
     """
     Create all the tables
     """
+    metadata = MetaData(bind=db.bind)
+    user_table = inspect_table(metadata, "core__users")
+
     # Create tables needed
     LocalUser_V0.__table__.create(db.bind)
     RemoteUser_V0.__table__.create(db.bind)
     db.commit()
 
     # Create the fields
-    metadata = MetaData(bind=db.bind)
-    user_table = inspect_table(metadata, "core__users")
-
     updated_column = Column(
         "updated",
         DateTime,
@@ -1476,6 +1476,12 @@ def federation_user_create_tables(db):
     )
     updated_column.create(user_table)
 
+    type_column = Column(
+        "type",
+        Unicode
+    )
+    type_column.create(user_table)
+
     name_column = Column(
         "name",
         Unicode
index ef37aef8fc6d3ba843ab418abde438942d64f5b9..41c367643cf8f26a24fbe3b9e76b18558af3099c 100644 (file)
@@ -237,6 +237,9 @@ class User(Base, UserMixin):
     bio = Column(UnicodeText)
     name = Column(Unicode)
 
+    # This is required for the polymorphic inheritance
+    type = Column(Unicode)
+
     created = Column(DateTime, nullable=False, default=datetime.datetime.utcnow)
     updated = Column(DateTime, nullable=False, default=datetime.datetime.utcnow)
 
@@ -245,6 +248,11 @@ class User(Base, UserMixin):
     # Lazy getters
     get_location = relationship("Location", lazy="joined")
 
+    __mapper_args__ = {
+        'polymorphic_identity': 'user',
+        'polymorphic_on': type
+    }
+
     def has_privilege(self, privilege, allow_admin=True):
         """
         This method checks to make sure a user has all the correct privileges
@@ -324,6 +332,10 @@ class LocalUser(User):
     uploaded = Column(Integer, default=0)
     upload_limit = Column(Integer)
 
+    __mapper_args__ = {
+        'polymorphic_identity': 'user_local'
+    }
+
     ## TODO
     # plugin data would be in a separate model
 
@@ -394,6 +406,10 @@ class RemoteUser(User):
     id = Column(Integer, ForeignKey("core__users.id"), primary_key=True)
     webfinger = Column(Unicode, unique=True)
 
+    __mapper_args__ = {
+        'polymorphic_identity': 'user_remote'
+    }
+
     def __repr__(self):
         return "<{0} #{1} {2}>".format(
             self.__class__.__name__,