在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()
注意:我想在不修改表格结构的情况下这样做。
答案 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()
的想法是将结果与每条记录相匹配。