Laravel Eloquent,如何用公式定义表关系?

时间:2016-10-12 06:18:31

标签: php mysql laravel laravel-5 eloquent

在Laravel Eloquent上,

如何将关系条件定义为表中不存在但根据表中的值计算的内容。

例如:

quarters                transactions
 _________ _________    _________ ___________
|   name  |  desc   |  |   id  |  date        |
 _________ _________    _________ ___________
|     1   | Jan-Mar |  |     1   | 2016-04-01 |
|     2   | Apr-Jun |  |     2   | 2016-05-01 |
|     3   | Jul-Sep |  |     3   | 2012-07-21 |
|     4   | Oct-Dec |  |     4   | 2014-01-31 |
 _________ _________    _________ ___________

这可以正常使用

SELECT 
FROM transactions tx
INNER JOIN quarters q ON q.name = ((MONTH(tx.date)+2)/3)

Quarters.php

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Quarters extends Model{

}

Transactions.php

namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Transactions extends Model{

    public function quater(){
        return $this->belongsTo('App\Models\Quarters' , '????', 'name') ;
    }
}

我应该在模型中定义什么才能做到: Transactions::where("some_field", "some_value")->with("quater")->get()

注意:我想在不修改表格结构的情况下这样做。

2 个答案:

答案 0 :(得分:1)

为了Eloquent Relationship,您需要Transection表中的另一列。例如:

      quarters                    transactions
 _________ _________    _________ ___________  ____________
|   name  |  desc   |  |   id    | quarter_id |    date    |
 _________ _________    _________ ___________  ____________
|     1   | Jan-Mar |  |     1   |      2     | 2016-04-01 |
|     2   | Apr-Jun |  |     2   |      2     | 2016-05-01 |
|     3   | Jul-Sep |  |     3   |      3     | 2012-07-21 |
|     4   | Oct-Dec |  |     4   |      1     | 2014-01-31 |
 _________ _________    _________ ___________ ______________

在此模式中quarter_id是表quarter_table的捕获。现在,您可以在模型中定义雄辩的关系,如下所示:

<强> Transactions.php

public function quarter(){
    return $this->belongsTo('App\Models\Quarters') ;
}

<强> Quarters.php

public function transactions(){
    return $this->hasMany('App\Models\Transactions') ;
}

<强>控制器

$transactions = Transactions::where('quarter_id', $someValue)->get()

or

$transactions = Transactions::with('quarter')->get();

答案 1 :(得分:0)

我最终创建了自己的Relation类

<?php

namespace App\Models;

use \Illuminate\Database\Eloquent\Builder;
use \Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Collection;
use App\Models\Quarter;

class HasManyQuarter extends HasMany {

    public function __construct($localKey, $object){
        $instance = new Quarter;
        $query = $instance->newQuery();
        $foreign_key = "name";

        parent::__construct($query, $object, $instance->getTable().'.'.$foreign_key, $localKey);
    }

    public function addEagerConstraints(array $models)
    {
        $keys = $this->getKeys($models, $this->localKey);
        $_keys = array();
        foreach($keys as $idx => $k){
            $_keys[$idx] = ( date("n", strtotime($k))+2 ) / 3; // Transform the Key
        }

        $this->query->whereIn($this->foreignKey, $keys);
    }

    public function match(array $models, Collection $results, $relation)
    {
        $dictionary = $this->buildDictionary($results);

        foreach ($models as $model) {
            $key = $model->getAttribute($this->localKey);

            $month = ( date("n", strtotime($key))+2 ) / 3; // Transform the Key

            if ( isset($dictionary[ $month ]) ) {
                $value = $this->getRelationValue($dictionary, $month, 'many');
                $model->setRelation($relation, $value);
            }

        }
        return $models;
    }
}

我的模特有:

public function quarter(){
   return new HasManyQuarter('date', $this);
}

我扩展了HasMany,因为我的情况是我的真实课程不是交易/季度。但这可以让任何人知道如何实现它。

改变查询的想法是addEagerConstraints,而match()的想法是将结果与每条记录相匹配。

Relations/HasMany.php

相关问题