sdispater / orator

The Orator ORM provides a simple yet beautiful ActiveRecord implementation.

Home Page:https://orator-orm.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

AttributeError when attaching many to many models with attributes

rpfk opened this issue · comments

The following example from the documentation is not working.

user.roles().attach([{1: {'attribute1': 'value1'}}, 2, 3])

When running a similar call in my project I get the following error.

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
..\..\..\miniconda3\envs\EchoDB\lib\site-packages\orator\orm\relations\belongs_to_many.py:660: in attach
    query.insert(self._create_attach_records(id, attributes))
..\..\..\miniconda3\envs\EchoDB\lib\site-packages\orator\orm\relations\belongs_to_many.py:676: in _create_attach_records
    records.append(self._attacher(key, value, attributes, timed))
..\..\..\miniconda3\envs\EchoDB\lib\site-packages\orator\orm\relations\belongs_to_many.py:684: in _attacher
    id, extra = self._get_attach_id(key, value, attributes)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <orator.orm.relations.belongs_to_many.BelongsToMany object at 0x0000026CFFBE3A48>
key = 1, value = {1: {'attribute1': 'value1'}}, attributes = None

    def _get_attach_id(self, key, value, attributes):
        """
        Get the attach record ID and extra attributes.
        """
        if isinstance(value, dict):
            key = list(value.keys())[0]
>           attributes.update(value[key])
E           AttributeError: 'NoneType' object has no attribute 'update'

..\..\..\miniconda3\envs\EchoDB\lib\site-packages\orator\orm\relations\belongs_to_many.py:699: AttributeError

The error can be solved by adding an empty dict as attributes such that the call looks like
user.roles().attach([{1: {'attribute1': 'value1'}}, 2, 3], {})

But my suggestion is to add the following to BelongsToMany.attach():

    def attach(self, id, attributes=None, touch=True):
        """
        Attach a model to the parent.
        """
        if isinstance(id, orator.orm.Model):
            id = id.get_key()

        query = self.new_pivot_statement()

        if not isinstance(id, list):
            id = [id]

        if attributes is None:
            attributes = {}

        query.insert(self._create_attach_records(id, attributes))

        if touch:
            self.touch_if_touching()