Skip to content
This repository has been archived by the owner on Jul 14, 2020. It is now read-only.

@classmethod not working #81

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

@classmethod not working #81

fletom opened this issue Feb 12, 2012 · 5 comments

Comments

@fletom
Copy link

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 as completed Feb 12, 2012
@fletom fletom reopened this Feb 12, 2012
@namlook
Copy link
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 as completed Feb 14, 2012
@fletom
Copy link
Author

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.

@namlook
Copy link
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
Copy link
Author

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.

@namlook
Copy link
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 mentioned this issue Apr 2, 2015
19 tasks
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants