diff --git a/crudkit/core/base.py b/crudkit/core/base.py index c7de93e..0540ec0 100644 --- a/crudkit/core/base.py +++ b/crudkit/core/base.py @@ -10,7 +10,13 @@ class CRUDMixin: updated_at = Column(DateTime, default=func.now(), onupdate=func.now()) def as_dict(self): - return {c.name: getattr(self, c.name) for c in self.__table__.columns} + # Combine all columns from all inherited tables + result = {} + for cls in self.__class__.__mro__: + if hasattr(cls, "__table__"): + for column in cls.__table__.columns: + result[column.name] = getattr(self, column.name) + return result class Version(Base): __tablename__ = "versions" diff --git a/crudkit/core/service.py b/crudkit/core/service.py index 98b6c86..a7da4e5 100644 --- a/crudkit/core/service.py +++ b/crudkit/core/service.py @@ -1,5 +1,5 @@ from typing import Type, TypeVar, Generic -from sqlalchemy.orm import Session +from sqlalchemy.orm import Session, with_polymorphic from crudkit.core.base import Version from crudkit.core.spec import CRUDSpec @@ -15,8 +15,16 @@ class CRUDService(Generic[T]): self.polymorphic = polymorphic self.supports_soft_delete = hasattr(model, 'is_deleted') + def get_query(self): + if self.polymorphic: + poly_model = with_polymorphic(self.model, '*') + return self.session.query(poly_model) + else: + base_only = with_polymorphic(self.model, [], flat=True) + return self.session.query(base_only) + def get(self, id: int, include_deleted: bool = False) -> T | None: - obj = self.session.get(self.model, id) + obj = self.get_query().filter_by(id=id).first() if obj is None: return None if self.supports_soft_delete and not include_deleted and obj.is_deleted: @@ -24,7 +32,7 @@ class CRUDService(Generic[T]): return obj def list(self, params=None) -> list[T]: - query = self.session.query(self.model) + query = self.get_query() if params: if self.supports_soft_delete: diff --git a/muck/app.py b/muck/app.py index f419bf5..60d7d3f 100644 --- a/muck/app.py +++ b/muck/app.py @@ -27,7 +27,7 @@ bootstrap_world(session) app = Flask(__name__) -dbref_service = CRUDService(Dbref, session) +dbref_service = CRUDService(Dbref, session, polymorphic=True) exit_service = CRUDService(Exit, session) player_service = CRUDService(Player, session) program_service = CRUDService(Program, session) @@ -42,4 +42,4 @@ app.register_blueprint(generate_crud_blueprint(Room, room_service), url_prefix=" app.register_blueprint(generate_crud_blueprint(Thing, thing_service), url_prefix="/api/things") if __name__ == "__main__": - app.run(debug=True) + app.run(debug=True, port=5050)