問題描述
我有一個模型列表,它通過它的belongsTo('Model') 關系繼承應該本質上屬于其對應模型所屬的制造商.
I have a model Listing that inherits through its belongsTo('Model') relationship should inherently belong to the Manufacturer that its corresponding Model belongs to.
這是我的列表模型:
public function model()
{
return $this->belongsTo('Model', 'model_id');
}
public function manufacturer()
{
return $this->belongsTo('Manufacturer', 'models.manufacturer_id');
/*
$manufacturer_id = $this->model->manufacturer_id;
return Manufacturer::find($manufacturer_id)->name;*/
}
和我的制造商模型:
public function listings()
{
return $this->hasManyThrough('Listing', 'Model', 'manufacturer_id', 'model_id');
}
public function models()
{
return $this->hasMany('Model', 'manufacturer_id');
}
我可以在視圖中回顯 $listing->model->name,但不能回顯 $listing->manufacturer->name.這會引發錯誤.我嘗試在 Listing 模型中注釋掉 2 行只是為了獲得效果,然后我可以 echo $listing->manufacturer() 并且這會起作用,但這并不能正確建立它們的關系.我該怎么做呢?謝謝.
I am able to echo $listing->model->name in a view, but not $listing->manufacturer->name. That throws an error. I tried the commented out 2 lines in the Listing model just to get the effect so then I could echo $listing->manufacturer() and that would work, but that doesn't properly establish their relationship. How do I do this? Thanks.
修訂列表模型(感謝回答者):
Revised Listing model (thanks to answerer):
public function model()
{
return $this->belongsTo('Model', 'model_id');
}
public function manufacturer()
{
return $this->belongsTo('Model', 'model_id')
->join('manufacturers', 'manufacturers.id', '=', 'models.manufacturer_id');
}
推薦答案
我找到了一個解決方案,但不是很簡單.我已經在下面發布了它,但我首先發布了我認為更好的解決方案.
I found a solution, but it's not extremely straight forward. I've posted it below, but I posted what I think is the better solution first.
您不應該直接從列表中訪問制造商,因為制造商僅適用于模型.雖然您可以從列表對象中預先加載制造商關系,但請參見下文.
You shouldn't be able to access manufacturer directly from the listing, since manufacturer applies to the Model only. Though you can eager-load the manufacturer relationships from the listing object, see below.
class Listing extends Eloquent
{
public function model()
{
return $this->belongsTo('Model', 'model_id');
}
}
class Model extends Eloquent
{
public function manufacturer()
{
return $this->belongsTo('manufacturer');
}
}
class Manufacturer extends Eloquent
{
}
$listings = Listing::with('model.manufacturer')->all();
foreach($listings as $listing) {
echo $listing->model->name . ' by ' . $listing->model->manufacturer->name;
}
為了讓您要求的解決方案發揮作用,我們費了一番周折.解決方案如下:
It took a bit of finagling, to get your requested solution working. The solution looks like this:
public function manufacturer()
{
$instance = new Manufacturer();
$instance->setTable('models');
$query = $instance->newQuery();
return (new BelongsTo($query, $this, 'model_id', $instance->getKeyName(), 'manufacturer'))
->join('manufacturers', 'manufacturers.id', '=', 'models.manufacturer_id')
->select(DB::raw('manufacturers.*'));
}
我首先處理查詢并從中構建響應.我希望創建的查詢類似于:
I started off by working with the query and building the response from that. The query I was looking to create was something along the lines of:
SELECT * FROM manufacturers ma
JOIN models m on m.manufacturer_id = ma.id
WHERE m.id in (?)
通常通過執行 return $this->belongsTo('Manufacturer');
select * from `manufacturers` where `manufacturers`.`id` in (?)
?
將替換為列表表中 manufacturer_id
列的值.此列不存在,因此將插入單個 0,并且您永遠不會返回制造商.
The ?
would be replaced by the value of manufacturer_id
columns from the listings table. This column doesn't exist, so a single 0 would be inserted and you'd never return a manufacturer.
在我想重新創建的查詢中,我受到了models.id
的約束.通過定義外鍵,我可以在我的關系中輕松訪問該值.于是關系變成了
In the query I wanted to recreate I was constraining by models.id
. I could easily access that value in my relationship by defining the foreign key. So the relationship became
return $this->belongsTo('Manufacturer', 'model_id');
這會產生與之前相同的查詢,但會使用 model_ids 填充 ?
.所以這會返回結果,但通常是不正確的結果.然后我打算更改我從中選擇的基表.這個值是從模型派生出來的,所以我把傳入的模型改成了Model
.
This produces the same query as it did before, but populates the ?
with the model_ids. So this returns results, but generally incorrect results. Then I aimed to change the base table that I was selecting from. This value is derived from the model, so I changed the passed in model to Model
.
return $this->belongsTo('Model', 'model_id');
我們現在已經模擬了模型關系,太好了,我真的什么都沒有.但至少現在,我可以連接到制造商表.所以我再次更新了關系:
We've now mimic the model relationship, so that's great I hadn't really got anywhere. But at least now, I could make the join to the manufacturers table. So again I updated the relationship:
return $this->belongsTo('Model', 'model_id')
->join('manufacturers', 'manufacturers.id', '=', 'models.manufacturer_id');
這讓我們更近了一步,生成了以下查詢:
This got us one step closer, generating the following query:
select * from `models`
inner join `manufacturers` on `manufacturers`.`id` = `models`.`manufacturer_id`
where `models`.`id` in (?)
從這里開始,我想將查詢的列限制為制造商列,為此我添加了選擇規范.這使關系變為:
From here, I wanted to limit the columns I was querying for to just the manufacturer columns, to do this I added the select specification. This brought the relationship to:
返回 $this->belongsTo('Model', 'model_id')->加入('制造商','manufacturers.id','=','models.manufacturer_id')->select(DB::raw('manufacturers.*'));
return $this->belongsTo('Model', 'model_id') ->join('manufacturers', 'manufacturers.id', '=', 'models.manufacturer_id') ->select(DB::raw('manufacturers.*'));
并得到查詢
select manufacturers.* from `models`
inner join `manufacturers` on `manufacturers`.`id` = `models`.`manufacturer_id`
where `models`.`id` in (?)
現在我們有一個 100% 有效的查詢,但是從關系返回的對象屬于 Model
類型而不是 Manufacturer
.這就是最后一點詭計出現的地方.我需要返回一個 Manufacturer,但希望它受到 where 子句中的
models表的約束.我創建了一個新的制造商實例并將表設置為
models`并手動創建關系.
Now we have a 100% valid query, but the objects being returned from the relationship are of type Model
not Manufacturer
. And that's where the last bit of trickery came in. I needed to return a Manufacturer, but wanted it to constrain by the
modelstable in the where clause. I created a new instance of Manufacturer and set the table to
models` and manually create the relationship.
需要注意的是,保存將不起作用.
$listing = Listing::find(1);
$listing->manufacturer()->associate(Manufacturer::create([]));
$listing->save();
這將創建一個新的制造商,然后將 listings.model_id
更新為新制造商的 ID.
This will create a new Manufacturer and then update listings.model_id
to the new manufacturer's id.
這篇關于如何在 Laravel 中設置 Eloquent 關系屬于通過另一個模型?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!