@classmethod not working #81

Open
fletom opened this Issue Feb 12, 2012 · 5 comments

Projects

None yet

2 participants

fletom commented Feb 12, 2012

I have the following code, with a class method.

@connection.register
class User(Document):
    __collection__ = 'users'
    structure = {
        'id': int,
        'screen_name': unicode,
        'token': unicode,
        'secret': unicode,
    }

    use_dot_notation = True

    @classmethod
    def create_or_update_by_id(cls, id, screen_name, token, secret):
        print (cls, cls())
        user = cls.find_one({'id': id}) or cls()

        user.id = id
        user.screen_name = screen_name
        user.token = token
        user.secret = secret

        user.validate()

        return user

But when I call it, with db.User.create_or_update_by_id(...) I get the following error:

TypeError: unbound method find_one() must be called with CallableUser instance as first argument (got mongo_query instance instead)

In other ORMs this works. Do class methods not work in MongoKit, or am I doing something wrong?

@fletom fletom closed this Feb 12, 2012
@fletom fletom reopened this Feb 12, 2012
Owner
namlook commented Feb 14, 2012

By design, all Documents accessed via db (db.Document.find()) are already instanciated. So you don't need to call @classmethod. Your User class would look like :

class User(Document):
    __collection__ = 'users'
    structure = {
        'id': int,
        'screen_name': unicode,
        'token': unicode,
        'secret': unicode,
    }

    use_dot_notation = True

    def create_or_update_by_id(self, id, screen_name, token, secret):
        self.id = id
        self.screen_name = screen_name
        self.token = token
        self.secret = secret
        self.validate() # why not saving here ?
        return self
@namlook namlook closed this Feb 14, 2012
fletom commented Feb 14, 2012

No, that doesn't work. The whole point is to create it only if the ID doesn't already exist. That's what the cls.find_one({'id': id}) or cls() line is for. If the find_one returns None, it creates a new User object by calling cls.

Owner
namlook commented Feb 14, 2012

Well, in this case:

class User(Document):
    __collection__ = 'users'
    structure = {
        'id': int,
        'screen_name': unicode,
        'token': unicode,
        'secret': unicode,
    }

    use_dot_notation = True

    def create_or_update_by_id(self, id, screen_name, token, secret):
        user = self.db.User.find_one({'_id': id}) or self.db.User()
        user.id = id
        user.screen_name = screen_name
        user.token = token
        user.secret = secret
        user.validate() # why not saving here ?
        return user
fletom commented Feb 14, 2012

That doesn't make any sense. Why would User have to specify itself in its methods? Or the db for that matter? And this is totally weird because self is an instance of User and you're using it to create new User objects. Completely un-Pythonic. Why don't class methods work? They are the only elegant solution.

Owner
namlook commented Feb 14, 2012

Yes, I know this is weird and completely un-Pythonic but this design inherits from a (very old) historical design. I tried to refactorise but the bad was already done (ie too many people were using MongoKit) and I don't have time anymore to fix this.

If you want you can provide a patch to fix this issue.

I re-open this ticket.

@namlook namlook reopened this Feb 14, 2012
@reorx reorx referenced this issue Apr 2, 2015
Open

MongoKit 1.0.0 Release!? #227

11 of 19 tasks complete
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment