orator icon indicating copy to clipboard operation
orator copied to clipboard

has_many_through select not working properly

Open alfonsocv12 opened this issue 3 years ago • 5 comments

Using the same example as the documentation where we have 3 tables countries, users and posts

countries
    id - integer
    name - string

users
    id - integer
    country_id - integer
    name - string

posts
    id - integer
    user_id - integer
    title - string

And the same model as the documentation

from orator.orm import has_many_through


class Country(Model):

    @has_many_through(User)
    def posts(self):
        return Post

If we make a query like this

Country.with('posts').find(1).to_json()

The result will be a json with the country and post like this

{
    id: 1,
    name: foo,
    posts: [
        {
            id: foo,
            user_id: foo,
            title: foo
        }
    ]
}

For this to happend without bringing the users table columns has_many_through has this two functions that returns the columns to select living out all the parent table columns.

The problem with the get function is that add_select overriding our self._query selects or get(columns=[]) because the get is on a Post model query, so we don't have access to filter the results.

    def _get_select_columns(self, columns=None):
        """
        Set the select clause for the relation query.

        :param columns: The columns
        :type columns: list

        :rtype: list
        """
        if columns == ["*"] or columns is None:
            columns = ["%s.*" % self._related.get_table()]
        return columns + ["%s.%s" % (self._parent.get_table(), self._first_key)]

    def get(self, columns=None):
        """
        Execute the query as a "select" statement.

        :type columns: list

        :rtype: orator.Collection
        """
        if columns is None:
            columns = ["*"]

        select = self._get_select_columns(columns)

        models = self._query.add_select(*select).get_models()

        if len(models) > 0:
            models = self._query.eager_load_relations(models)

        return self._related.new_collection(models)

alfonsocv12 avatar Mar 25 '21 22:03 alfonsocv12

I have solve the problem on this pull request let me know what i need to change for this to be approved or if theres another way to do it

alfonsocv12 avatar Mar 25 '21 23:03 alfonsocv12

@alfonsocv12 have you looked into Masonite ORM?

It's basically an almost drop in replacement of Orator. https://github.com/MasoniteFramework/orm

Orator will not be receiving updated for the foreseeable future and I don't want you to waste too much time on PRs that won't get merged

josephmancuso avatar Mar 26 '21 01:03 josephmancuso

Excelent, Thank you @josephmancuso

alfonsocv12 avatar Mar 26 '21 01:03 alfonsocv12

@josephmancuso You remove has_many_through from masonite orm because its better to use belongs_to_many, btw I can add the functionality if you want

alfonsocv12 avatar Mar 26 '21 01:03 alfonsocv12

Sure! Let me know if you have questions. It's useful to read the ORM white paper which explains how all the pieces of the ORM are built and how they relate with each other

josephmancuso avatar Mar 26 '21 01:03 josephmancuso