Skip to content

Commit

Permalink
user preferences: use JSON type for 'value' column, no need for _valu…
Browse files Browse the repository at this point in the history
…e column+properties. Added 'preferences' backref to User model
  • Loading branch information
Bertrand Mathieu committed Jun 17, 2013
1 parent 3784805 commit ed1a9cb
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 25 deletions.
26 changes: 9 additions & 17 deletions abilian/services/preferences/models.py
Original file line number Diff line number Diff line change
@@ -1,39 +1,31 @@
"""
Models for user preferences.
"""
import json
from __future__ import absolute_import

from sqlalchemy import Column, Integer, String, ForeignKey, Unicode
from sqlalchemy.orm import relation
from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint
from sqlalchemy.orm import relation, backref

from abilian.core.extensions import db
from abilian.core.subjects import User

from abilian.core.sqlalchemy import JSON

class UserPreference(db.Model):
"""An atom of user preference."""

__tablename__ = 'user_preference'
__table_args__ = (UniqueConstraint('user_id', 'key'),)

#: Unique id for this preference.
id = Column(Integer, primary_key=True, autoincrement=True)

#: The user who set this preference.
user = relation(User)
user = relation(
User, backref=backref('preferences', cascade="all, delete, delete-orphan")
)
user_id = Column(ForeignKey(User.id))

#: The key
key = Column(String, nullable=False)

#: The value
_value = Column(Unicode, nullable=False)

@property
def value(self):
return json.loads(self._value)

@value.setter
def value(self, value):
self._value = unicode(json.dumps(value))

# TODO: use JSON to serialize values?
value = Column(JSON, nullable=False)
13 changes: 6 additions & 7 deletions abilian/services/preferences/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,15 @@ def get_preferences(self, user=None):
"""
if user is None:
user = current_user
preferences = UserPreference.query.filter(UserPreference.user_id == user.id).all()
return { pref.key: pref.value for pref in preferences}
return { pref.key: pref.value for pref in user.preferences }

def set_preferences(self, user=None, **kwargs):
"""Sets preferences from keyword arguments.
"""
if user is None:
user = current_user

preferences = UserPreference.query.filter(UserPreference.user_id == user.id).all()
d = { pref.key: pref for pref in preferences}
d = { pref.key: pref for pref in user.preferences }
for k, v in kwargs.items():
if k in d:
d[k].value = v
Expand All @@ -61,9 +59,10 @@ def clear_preferences(self, user=None):
if user is None:
user = current_user

preferences = UserPreference.query.filter(UserPreference.user_id == user.id).all()
for pref in preferences:
db.session.delete(pref)
# don't delete UserPreference 1 by 1 with session.delete, else
# user.preferences is not updated until commit() (not flush()). see
# http://docs.sqlalchemy.org/en/rel_0_7/orm/session.html#deleting-from-collections
user.preferences = []

def register_panel(self, panel):
self.panels.append(panel)
Expand Down
4 changes: 3 additions & 1 deletion abilian/services/preferences/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
from abilian.testing import BaseTestCase

from .service import PreferenceService

from .models import UserPreference

class PreferencesTestCase(BaseTestCase):

def test_preferences(self):
user = User(email=u"test@example.com")
assert UserPreference.query.all() == []

preference_service = PreferenceService()

Expand All @@ -25,6 +26,7 @@ def test_preferences(self):

preferences = preference_service.get_preferences(user)
self.assertEquals(preferences, {})
assert UserPreference.query.all() == []

def test_preferences_with_various_types(self):
user = User(email=u"test@example.com")
Expand Down

0 comments on commit ed1a9cb

Please sign in to comment.