Skip to content

Instantly share code, notes, and snippets.

@pionl
Last active February 29, 2020 13:08
Show Gist options
  • Save pionl/fae06d53e6e9a66ca18d to your computer and use it in GitHub Desktop.
Save pionl/fae06d53e6e9a66ca18d to your computer and use it in GitHub Desktop.

Revisions

  1. Martin Kluska revised this gist Dec 23, 2015. 1 changed file with 31 additions and 3 deletions.
    34 changes: 31 additions & 3 deletions ModelJoinTrait.php
    Original file line number Diff line number Diff line change
    @@ -11,11 +11,18 @@
    *
    * Prefils the relations array.
    *
    * @property array $relationAliases A list of relations that has different method name than the table. Can be defined
    * in model like this:
    * protected $relationAliases = [
    * "activity_type" => "type"
    * ];
    *
    * @package App\Traits\Models
    */
    trait ModelJoinTrait
    {


    /**
    * This determines the foreign key relations automatically to prevent the need to figure out the columns.
    *
    @@ -100,9 +107,8 @@ public function setRawAttributes(array $attributes, $sync = false)
    if (!empty($tableAttributes)) {
    foreach ($tableAttributes as $tableFull => $newAttributes) {

    // check if its relation function. The table names can
    // be in plurar
    $table = Str::singular($tableFull);
    // get the tabale name method
    $table = $this->getBelongsToMethodName($tableFull);

    // check if exists
    if (method_exists($this, $table)) {
    @@ -144,4 +150,26 @@ public function getAttributesByTablePrefix(array $attributes)

    return $tableAttributes;
    }

    /**
    * Returns the method name for given table
    *
    * @param string $tableFull like activity_types
    *
    * @return string as activity_type
    */
    protected function getBelongsToMethodName($tableFull)
    {
    // check if its relation function. The table names can
    // be in plurar
    $table = Str::singular($tableFull);

    // support the aliases for changing the table name
    // to shorted version
    if (isset($this->relationAliases[$table])) {
    return $this->relationAliases[$table];
    }

    return $table;
    }
    }
  2. Martin Kluska revised this gist Dec 15, 2015. 1 changed file with 7 additions and 7 deletions.
    14 changes: 7 additions & 7 deletions ModelJoinTrait.php
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,6 @@
    <?php
    namespace Pion\Traits\Models;
    use Illuminate\Database\Eloquent\Builder;
    use Illuminate\Database\Eloquent\Relations\Relation;

    use Illuminate\Database\Query\Expression;
    use Illuminate\Support\Str;

    @@ -16,7 +15,6 @@
    */
    trait ModelJoinTrait
    {
    protected $modelJoined = array();

    /**
    * This determines the foreign key relations automatically to prevent the need to figure out the columns.
    @@ -28,7 +26,8 @@ trait ModelJoinTrait
    * @param string $operatorOrCollumns ON condition operator
    * @param string $type join type (left, right, '', etc)
    * @param bool $where custom where condition
    * @param array $collumns if you will not pass collumns, it will retreive the collumn listing. If you pass null
    * @param array $collumns if you will not pass collumns, it will retreive the collumn listing.
    * If you pass null
    * it will not get any data from the model.
    * all collumns *
    *
    @@ -60,7 +59,8 @@ public function scopeModelJoin($query, $relation_name, $operatorOrCollumns = '='
    *
    * @return \Illuminate\Database\Query\Builder
    */
    public function scopeJoinWithSelect($query, $table, $one, $operatorOrCollumns, $two, $type = "left", $where = false, $collumns = array())
    public function scopeJoinWithSelect($query, $table, $one, $operatorOrCollumns, $two, $type = "left", $where = false,
    $collumns = array())
    {
    // if the operator collumns are in
    if (is_array($operatorOrCollumns) || is_null($operatorOrCollumns)) {
    @@ -110,12 +110,12 @@ public function setRawAttributes(array $attributes, $sync = false)

    if (is_object($relation) && method_exists($relation, "getRelated")) {

    $instance = $relation->getRelated()->newInstance($newAttributes, true);
    $instance = $relation->getRelated()->newFromBuilder($newAttributes);

    $this->setRelation($table, $instance);

    foreach ($newAttributes as $key => $attribute) {
    unset($attributes[$key]);
    unset($attributes[$tableFull.".".$key]);
    }
    }
    }
  3. Martin Kluska revised this gist Dec 15, 2015. 1 changed file with 16 additions and 11 deletions.
    27 changes: 16 additions & 11 deletions ModelJoinTrait.php
    Original file line number Diff line number Diff line change
    @@ -28,7 +28,8 @@ trait ModelJoinTrait
    * @param string $operatorOrCollumns ON condition operator
    * @param string $type join type (left, right, '', etc)
    * @param bool $where custom where condition
    * @param array $collumns if you will not pass collumns, it will retreive the collumn listing via
    * @param array $collumns if you will not pass collumns, it will retreive the collumn listing. If you pass null
    * it will not get any data from the model.
    * all collumns *
    *
    * @return \Illuminate\Database\Query\Builder
    @@ -50,29 +51,33 @@ public function scopeModelJoin($query, $relation_name, $operatorOrCollumns = '='
    * @param \Illuminate\Database\Query\Builder $query
    * @param string $table join the table
    * @param string $one joins first parameter
    * @param string $operatorOrCollumns
    * @param string|array|null $operatorOrCollumns operator condition or collums list
    * @param string $two joins two parameter
    * @param string $type join type (left, right, '', etc)
    * @param bool|false $where custom where condition
    * @param array $collumns if you will not pass collumns, it will retreive the collumn listing via
    * @param array $collumns if you will not pass collumns, it will retreive the collumn listing. If you pass null
    * it will not get any data from the model.
    *
    * @return \Illuminate\Database\Query\Builder
    */
    public function scopeJoinWithSelect($query, $table, $one, $operatorOrCollumns, $two, $type = "left", $where = false, $collumns = array())
    {
    // if the operator collumns are in
    if (is_array($operatorOrCollumns)) {
    if (is_array($operatorOrCollumns) || is_null($operatorOrCollumns)) {
    $collumns = $operatorOrCollumns;
    $operatorOrCollumns = "=";
    }

    // if there is no specific collumns, lets get all
    if (empty($collumns)) {
    $collumns = \Schema::getColumnListing($table);
    }
    if (!is_null($collumns)) {
    // if there is no specific collumns, lets get all
    if (empty($collumns)) {
    $collumns = \Schema::getColumnListing($table);
    }

    // build the table values prefixed by the table to ensure unique values
    foreach ($collumns as $related_column) {
    $query->addSelect(new Expression("`$table`.`$related_column` AS `$table.$related_column`"));
    // build the table values prefixed by the table to ensure unique values
    foreach ($collumns as $related_column) {
    $query->addSelect(new Expression("`$table`.`$related_column` AS `$table.$related_column`"));
    }
    }

    return $query->join($table, $one, $operatorOrCollumns, $two, $type, $where);
  4. Martin Kluska revised this gist Oct 21, 2015. No changes.
  5. Martin Kluska revised this gist Oct 21, 2015. 1 changed file with 22 additions and 12 deletions.
    34 changes: 22 additions & 12 deletions ModelJoinTrait.php
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,6 @@
    <?php
    namespace App\Traits\Models;
    namespace Pion\Traits\Models;
    use Illuminate\Database\Eloquent\Builder;
    use Illuminate\Database\Eloquent\Relations\Relation;
    use Illuminate\Database\Query\Expression;
    use Illuminate\Support\Str;
    @@ -9,7 +10,7 @@
    *
    * Trait to create model join for scope with detection of model in the attributes.
    *
    * Prefils the relations array
    * Prefils the relations array.
    *
    * @package App\Traits\Models
    */
    @@ -39,21 +40,31 @@ public function scopeModelJoin($query, $relation_name, $operatorOrCollumns = '='

    $relation = $this->$relation_name();
    $table = $relation->getRelated()->getTable();
    $one = $relation->getQualifiedParentKeyName();
    $one = $relation->getRelated()->getQualifiedKeyName();
    $two = $relation->getForeignKey();

    return $this->scopeJoinWithSelect($query, $table, $one, $operatorOrCollumns, $two, $type, $where, $collumns);
    }

    /**
    * @param \Illuminate\Database\Query\Builder $query
    * @param string $table join the table
    * @param string $one joins first parameter
    * @param string $operatorOrCollumns
    * @param string $two joins two parameter
    * @param string $type join type (left, right, '', etc)
    * @param bool|false $where custom where condition
    * @param array $collumns if you will not pass collumns, it will retreive the collumn listing via
    * @return \Illuminate\Database\Query\Builder
    */
    public function scopeJoinWithSelect($query, $table, $one, $operatorOrCollumns, $two, $type = "left", $where = false, $collumns = array())
    {
    // if the operator collumns are in
    if (is_array($operatorOrCollumns)) {
    $collumns = $operatorOrCollumns;
    $operatorOrCollumns = "=";
    }

    // if the query has missing collumns list, we need to add select for all collumns
    // of this table
    if (empty($query->columns)) {
    $query->select($this->getTable().".*");
    }

    // if there is no specific collumns, lets get all
    if (empty($collumns)) {
    $collumns = \Schema::getColumnListing($table);
    @@ -64,8 +75,6 @@ public function scopeModelJoin($query, $relation_name, $operatorOrCollumns = '='
    $query->addSelect(new Expression("`$table`.`$related_column` AS `$table.$related_column`"));
    }

    $this->modelJoined[$table] = $relation;

    return $query->join($table, $one, $operatorOrCollumns, $two, $type, $where);
    }

    @@ -95,9 +104,10 @@ public function setRawAttributes(array $attributes, $sync = false)
    $relation = $this->$table();

    if (is_object($relation) && method_exists($relation, "getRelated")) {

    $instance = $relation->getRelated()->newInstance($newAttributes, true);

    $this->relations[$table] = $instance;
    $this->setRelation($table, $instance);

    foreach ($newAttributes as $key => $attribute) {
    unset($attributes[$key]);
  6. Martin Kluska revised this gist Aug 20, 2015. 1 changed file with 70 additions and 5 deletions.
    75 changes: 70 additions & 5 deletions ModelJoinTrait.php
    Original file line number Diff line number Diff line change
    @@ -1,16 +1,22 @@
    <?php
    namespace App\Traits\Models;
    use Illuminate\Database\Eloquent\Relations\Relation;
    use Illuminate\Database\Query\Expression;
    use Illuminate\Support\Str;

    /**
    * Class ModelJoinTrait
    *
    * Trait to create model join for scope
    * Trait to create model join for scope with detection of model in the attributes.
    *
    * Prefils the relations array
    *
    * @package App\Traits\Models
    */
    trait ModelJoinTrait
    {
    protected $modelJoined = array();

    /**
    * This determines the foreign key relations automatically to prevent the need to figure out the columns.
    *
    @@ -50,18 +56,77 @@ public function scopeModelJoin($query, $relation_name, $operatorOrCollumns = '='

    // if there is no specific collumns, lets get all
    if (empty($collumns)) {
    foreach (\Schema::getColumnListing($table) as $related_column) {
    $query->addSelect(new Expression("`$table`.`$related_column` AS `$table.$related_column`"));
    }
    $collumns = \Schema::getColumnListing($table);
    }

    // build the table values prefixed by the table
    // build the table values prefixed by the table to ensure unique values
    foreach ($collumns as $related_column) {
    $query->addSelect(new Expression("`$table`.`$related_column` AS `$table.$related_column`"));
    }

    $this->modelJoined[$table] = $relation;

    return $query->join($table, $one, $operatorOrCollumns, $two, $type, $where);
    }

    /**
    * Overides the basic attributes filling with check if the attributes has
    * collumns with table format. Checks if we can make a model based on table prefix and
    * relation definition. Tested on BelonstTo and left join
    *
    * @param array $attributes
    * @param bool|false $sync
    * @return mixed
    */
    public function setRawAttributes(array $attributes, $sync = false)
    {
    // find
    $tableAttributes = $this->getAttributesByTablePrefix($attributes);

    if (!empty($tableAttributes)) {
    foreach ($tableAttributes as $tableFull => $newAttributes) {

    // check if its relation function. The table names can
    // be in plurar
    $table = Str::singular($tableFull);

    // check if exists
    if (method_exists($this, $table)) {
    $relation = $this->$table();

    if (is_object($relation) && method_exists($relation, "getRelated")) {
    $instance = $relation->getRelated()->newInstance($newAttributes, true);

    $this->relations[$table] = $instance;

    foreach ($newAttributes as $key => $attribute) {
    unset($attributes[$key]);
    }
    }
    }
    }
    }

    return parent::setRawAttributes($attributes, $sync);
    }

    /**
    * Loops all the attributes and finds only values that have prefix format
    * TABLE.COLLUMN
    * @param array $attributes
    * @return array
    */
    public function getAttributesByTablePrefix(array $attributes)
    {
    $tableAttributes = array();

    foreach ($attributes as $attribute => $value) {
    // check prefix format
    if (preg_match("/([^\.]+)\.(.*)/", $attribute, $matches)) {
    $tableAttributes[$matches[1]][$matches[2]] = $value;
    }
    }

    return $tableAttributes;
    }
    }
  7. Martin Kluska created this gist Aug 20, 2015.
    67 changes: 67 additions & 0 deletions ModelJoinTrait.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,67 @@
    <?php
    namespace App\Traits\Models;
    use Illuminate\Database\Query\Expression;

    /**
    * Class ModelJoinTrait
    *
    * Trait to create model join for scope
    *
    * @package App\Traits\Models
    */
    trait ModelJoinTrait
    {
    /**
    * This determines the foreign key relations automatically to prevent the need to figure out the columns.
    *
    * Based on http://laravel-tricks.com/tricks/automatic-join-on-eloquent-models-with-relations-setup
    *
    * @param \Illuminate\Database\Query\Builder $query
    * @param string $relation_name the function that return the relation
    * @param string $operatorOrCollumns ON condition operator
    * @param string $type join type (left, right, '', etc)
    * @param bool $where custom where condition
    * @param array $collumns if you will not pass collumns, it will retreive the collumn listing via
    * all collumns *
    *
    * @return \Illuminate\Database\Query\Builder
    *
    * @link http://laravel-tricks.com/tricks/automatic-join-on-eloquent-models-with-relations-setup
    */
    public function scopeModelJoin($query, $relation_name, $operatorOrCollumns = '=', $type = 'left',
    $where = false, $collumns = array()) {

    $relation = $this->$relation_name();
    $table = $relation->getRelated()->getTable();
    $one = $relation->getQualifiedParentKeyName();
    $two = $relation->getForeignKey();

    // if the operator collumns are in
    if (is_array($operatorOrCollumns)) {
    $collumns = $operatorOrCollumns;
    $operatorOrCollumns = "=";
    }

    // if the query has missing collumns list, we need to add select for all collumns
    // of this table
    if (empty($query->columns)) {
    $query->select($this->getTable().".*");
    }

    // if there is no specific collumns, lets get all
    if (empty($collumns)) {
    foreach (\Schema::getColumnListing($table) as $related_column) {
    $query->addSelect(new Expression("`$table`.`$related_column` AS `$table.$related_column`"));
    }
    }

    // build the table values prefixed by the table
    foreach ($collumns as $related_column) {
    $query->addSelect(new Expression("`$table`.`$related_column` AS `$table.$related_column`"));
    }

    return $query->join($table, $one, $operatorOrCollumns, $two, $type, $where);

    }

    }