GithubHelp home page GithubHelp logo

paulhenri-l / laravel-sti Goto Github PK

View Code? Open in Web Editor NEW
17.0 17.0 0.0 34 KB

Single table inheritance with Laravel/Eloquent

Home Page: https://packagist.org/packages/phl/laravel-sti

License: MIT License

PHP 100.00%
eloquent laravel single-table-inheritance

laravel-sti's People

Contributors

paulhenri-l avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

laravel-sti's Issues

Queries having alias

Hi,
Not too sure if you are still maintaining this repo.
There are few issues that I found and just letting you know if you would like to have them fixed.

  1. composer.json is set to php ^7.3; thus we are not able to use this repo directly since we are on php 8.1 and Laravel 9.
  2. Having a self reference BelongsToMany relation, using withCount will generate a wrong query. On line 1318, where Laravel will change model's table name to an alias it generated:
public function getRelationExistenceQueryForSelfJoin(Builder $query, Builder $parentQuery, $columns = ['*'])
    {
        $query->select($columns);

        $query->from($this->related->getTable().' as '.$hash = $this->getRelationCountHash());

        $this->related->setTable($hash);     <-- Here it will changed the table name to an alias it generated

        $this->performJoin($query);

        return parent::getRelationExistenceQuery($query, $parentQuery, $columns);
    }

But later on when it tries to retrieve and generate the query, STI generates a new model and thus returned model's default table name. The generated query looks like this:

select distinct `products`.*, 
           (     select count(*) 
                   from `products` as `laravel_reserved_0` 
             inner join `product_has_components` on `products`.`product_id` = `product_has_components`.`product_id` 
                  where `products`.`product_id` = `product_has_components`.`component_id` 
                    and `type` = ? and `products`.`deleted_at` is null
           ) as `use_bys_count`
 from `products` 
where `type` = ? and `products`.`deleted_at` is null

Note that the count query is having an alias but other parts of the query is not using that alias as its table name.
The fix I come out with is adding a private attribute and sets & gets table name from it:

    /**
     * Sets the name of the table.
     */
    public function setTable($table)
    {
        if (static::isSTIParent()) {
            return parent::setTable($table);
        } // end of if

        if ($this->_stiParent == null) {
            $this->_stiParent = $this->newSTIParent();
        } // end of if

        return $this->_stiParent->setTable($table);
    } // end of method

    /**
     * Always use the STI parent model's table.
     */
    public function getTable()
    {
        if (static::isSTIParent()) {
            return parent::getTable();
        } // end of if

        if ($this->_stiParent == null) {
            $this->_stiParent = $this->newSTIParent();
        } // end of if

        return $this->_stiParent->getTable();
    } // end of method
  1. You have static::inSTIParent(); Do you mean isSTIParent?
  2. Add table name to 'type' column to avoid name conflict:
/**
     * Pass the given type through the type map before searching for it.
     */
    public function scopeWhereSTIType(Builder $query, $type)
    {
        return $query->where($this->getTable() . '.' .static::typeKey(), TypeMap::getAlias($type));
    } // end of method

Great job on this repo. I have been using this repo for many years without much problem.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.