Created
December 20, 2016 07:45
-
-
Save xxzefgh/3022fee8afa53e45a6b89da3f16b3815 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App; | |
use Illuminate\Support\Arr; | |
use Illuminate\Support\Str; | |
use Illuminate\Database\Eloquent\Model; | |
use Illuminate\Database\Eloquent\Builder; | |
use Illuminate\Database\Eloquent\Relations\Relation; | |
use Illuminate\Database\Eloquent\Relations\BelongsTo; | |
class BelongsToMorph extends BelongsTo | |
{ | |
/** | |
* The name of the polymorphic relation. | |
* | |
* @var string | |
*/ | |
protected $morphName; | |
/** | |
* The type of the polymorphic relation. | |
* | |
* @var string | |
*/ | |
protected $morphType; | |
public function __construct(Builder $query, Model $parent, $name, $type, $id, $otherKey, $relation) | |
{ | |
$this->morphName = $name; | |
$this->morphType = $type; | |
parent::__construct($query, $parent, $id, $otherKey, $relation); | |
} | |
/** | |
* Add the constraints for a relationship query. | |
* | |
* @param \Illuminate\Database\Eloquent\Builder $query | |
* @param \Illuminate\Database\Eloquent\Builder $parent | |
* @param array|mixed $columns | |
* @return \Illuminate\Database\Eloquent\Builder | |
*/ | |
public function getRelationQuery(Builder $query, Builder $parent, $columns = ['*']) | |
{ | |
$table = $this->getParent()->getTable(); | |
$query = parent::getRelationQuery($query, $parent, $columns); | |
return $query->where("{$table}.{$this->morphType}", '=', $this->morphName); | |
} | |
/** | |
* Get the results of the relationship. | |
* | |
* @return mixed | |
*/ | |
public function getResults() | |
{ | |
if ($this->getParent()->{$this->morphType} === $this->morphName) { | |
return $this->query->first(); | |
} | |
return null; | |
} | |
/** | |
* Get the polymorphic relationship columns. | |
* | |
* @param string $name | |
* @param string $type | |
* @param string $id | |
* @return array | |
*/ | |
protected static function getMorphs($name, $type, $id) | |
{ | |
$type = $type ?: $name.'_type'; | |
$id = $id ?: $name.'_id'; | |
return [$type, $id]; | |
} | |
/** | |
* Define an inverse morph relationship. | |
* | |
* @param Model $parent | |
* @param string $related | |
* @param string $name | |
* @param string $type | |
* @param string $id | |
* @param string $otherKey | |
* @param string $relation | |
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo | |
*/ | |
public static function build(Model $parent, $related, $name, $type = null, $id = null, $otherKey = null, $relation = null) | |
{ | |
// If no relation name was given, we will use this debug backtrace to extract | |
// the calling method's name and use that as the relationship name as most | |
// of the time this will be what we desire to use for the relationships. | |
if (is_null($relation)) { | |
list($current, $caller) = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2); | |
$relation = $caller['function']; | |
} | |
$morphName = Arr::get(array_flip(Relation::morphMap()), $related, $related); | |
list($type, $id) = self::getMorphs(Str::snake($name), $type, $id); | |
$instance = new $related; | |
// Once we have the foreign key names, we'll just create a new Eloquent query | |
// for the related models and returns the relationship instance which will | |
// actually be responsible for retrieving and hydrating every relations. | |
$query = $instance->newQuery(); | |
$otherKey = $otherKey ?: $instance->getKeyName(); | |
return new BelongsToMorph($query, $parent, $morphName, $type, $id, $otherKey, $relation); | |
} | |
} |
This is cool. I've used it.
Thank for this magic brother 👍
Hi, Thank you for your solution. But i have a problem working with it. I have 4 relations BelongsToMorph and when i use has or whereHas some of them return another relations.
`public function salaryAdvance()
{
return BelongsToMorph::build($this, SalaryAdvance::class, 'mainledgerable');
}
public function tuition()
{
return BelongsToMorph::build($this, CollectTuitionFee::class, 'mainledgerable');
}
public function fiOther()
{
return BelongsToMorph::build($this, FiOther::class, 'mainledgerable');
}
public function payrollSlip()
{
return BelongsToMorph::build($this, PayrollSlip::class, 'mainledgerable');
}`
MainLedger::has('tuition','>=',1)->get();
$rows = MainLedger::where(function($query) use ($request){ $type = $request->type; if ($type){ $query->whereHas('tuition', function($query) use ($type) { $query->where('type',$type); }, '>=', 1); } }) ->orderBy('id','desc');
This code return object of another relations like payrollSlip or salaryAdvance
thank you very much !
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@ibi001 where do I put this file and do I need to add any references anywhere?
Thanks in advance,
K...