]> asedeno.scripts.mit.edu Git - bluechips.git/commitdiff
Normalized the implementation of tags
authorRay Speth <speth@mit.edu>
Thu, 18 Mar 2010 04:11:49 +0000 (00:11 -0400)
committerAlejandro R. Sedeño <asedeno@mit.edu>
Wed, 23 Feb 2011 02:39:20 +0000 (21:39 -0500)
bluechips/controllers/spend.py
bluechips/model/__init__.py
bluechips/model/expenditure.py
bluechips/model/tag.py

index 9caa1b390defd714c292efb431cae9ff506a68ff..ddd0a3cd45947b3fbe9d3e466ebce6c6f33d8901 100644 (file)
@@ -112,7 +112,7 @@ class SpendController(BaseController):
                 share = shares_by_user.get(user, '')
                 c.values['shares-%d.amount' % ii] = share
 
-            c.values['tags'] = ', '.join([tag.tag for tag in c.expenditure.tags])
+            c.values['tags'] = ', '.join(c.expenditure.tags)
 
         return render('/spend/index.mako')
 
@@ -146,7 +146,8 @@ class SpendController(BaseController):
             split_dict[user] = amount
             split_text_dict[user] = amount_text
         e.split(split_dict, split_text_dict)
-        e.tag(tags)
+        e.tags.clear()
+        e.tags |= tags
 
         meta.Session.commit()
        
index 11fb0e5262cb193ef98c8d69cd122f0b04fcf624..fa8d7a88239b5b94e5fa202461847a7a29b2c440 100644 (file)
@@ -56,10 +56,15 @@ splits = sa.Table('splits', meta.metadata,
 
 tags = sa.Table('tags', meta.metadata,
                 sa.Column('id', sa.types.Integer, primary_key=True),
-                sa.Column('expenditure_id', sa.types.Integer,
-                          sa.ForeignKey('expenditures.id'), nullable=False),
-                sa.Column('tag', sa.Text, nullable=False))
+                sa.Column('name', sa.Text))
 
+tag_to_expense_map = sa.Table('tag_to_expense_map', meta.metadata,
+                              sa.Column('tag_id', sa.types.Integer,
+                                        sa.ForeignKey('tags.id'),
+                                        primary_key=True),
+                              sa.Column('expenditure_id', sa.types.Integer,
+                                        sa.ForeignKey('expenditures.id'),
+                                        primary_key=True))
 
 subitems = sa.Table('subitems', meta.metadata,
                     sa.Column('id', sa.types.Integer, primary_key=True),
@@ -96,8 +101,8 @@ orm.mapper(Expenditure, expenditures,
            properties={
         'splits': orm.relation(Split, backref='expenditure',
                                cascade='all, delete'),
-        'tags': orm.relation(Tag, backref='expenditure',
-                             cascade='all, delete'),
+        '_tags': orm.relation(Tag, secondary=tag_to_expense_map,
+                             collection_class=set, cascade='all, delete'),
         'subitems': orm.relation(Subitem, backref='expenditure',
                                  cascade='all, delete')
 })
index 6b3b1cb242c6c1e4ecd4de1fef70e537870cc3b6..d732fbe18328c9d6b909bbb52635f0f1775b6033 100644 (file)
@@ -1,8 +1,10 @@
+from sqlalchemy.ext.associationproxy import association_proxy
+
 from bluechips.model.user import User
 from bluechips.model.split import Split
 from bluechips.model import meta
 from bluechips.model.types import Currency
-from bluechips.model.tag import Tag
+from bluechips.model.tag import create_tag
 from decimal import Decimal
 from datetime import datetime
 import random
@@ -16,6 +18,8 @@ class Expenditure(object):
         if self.date == None:
             self.date = datetime.now()
     
+    tags = association_proxy('_tags', 'name', creator=create_tag)
+
     def __repr__(self):
         return '<Expenditure: spender: %s spent: %s>' % (self.spender,
                                                          self.amount)
@@ -75,14 +79,6 @@ class Expenditure(object):
             s = Split(self, user, share, split_text_dict[user])
             meta.Session.add(s)
 
-    def tag(self, tags):
-        map(meta.Session.delete,
-            meta.Session.query(Tag).filter_by(expenditure_id=self.id))
-
-        for tag in tags:
-            t = Tag(self, tag)
-            meta.Session.add(t)
-
     def involves(self, user):
         "Returns True if ``user`` is involved in this expenditure."
         return (any((split.user == user) and (split.share != 0)
index c6a3661c28bcddc8dad27be0b633c9a252233f00..e2d2ef449ba5c6400e8a70c3f0b6d1e8f2a360dc 100644 (file)
@@ -1,10 +1,20 @@
+from bluechips.model import meta
+
 class Tag(object):
-    def __init__(self, expenditure=None, tag=u""):
-        self.expenditure = expenditure
-        self.tag = tag
+    def __init__(self, name=u""):
+        self.name = name
 
     def __repr__(self):
-        return '<Tag: expense: %s value: %s>' % (self.expenditure,
-                                                            self.tag)
+        return '<Tag: name: %s>' % (self.name)
+
+def create_tag(name):
+    if not isinstance(name, unicode):
+        raise TypeError('%r is not a unicode object' % type(name).__name__)
+    t = meta.Session.query(Tag).filter_by(name=name).first()
+    if t is None:
+        t = Tag(name)
+
+    return t
+
 
 __all__ = ['Tag']