Laravel 5.6.17 模型在多个表上有一个
Laravel 5.6.17 Model hasOne over multiple tables
我对 Laravel 很陌生,现在我正在尝试将以前的应用程序的一部分从一个小型的自写框架移动到 Laravel 中。地址簿是多语言的,因此 table 结构稍微复杂一些。
db-structure
这是我的源代码:
- AddressBookController.php
namespace App\Http\Controllers;
use App\AddressBook as AB;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
class AddressBookController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$entries = AB::all();
return view('addressBook')->with([
'class' => __CLASS__,
'function' => __FUNCTION__,
'line' => __LINE__,
'entries' => $entries,
]);
}
}
型号AddressBook.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class AddressBook extends Model
{
protected $table = 'address';
protected $primaryKey = 'address_id';
protected $keyType = 'int';
public $incrementing = true;
public $timestamps = false;
protected $searchable = [
'columns' => [
'address.address_surname' => 10,
'address.address_company' => 5,
'address.address_vatid' => 2,
],
];
public function country() {
return $this->hasOne('country', 'country_id', 'country_id');
}
public function addresstype() {
return $this->hasOne('addresstype', 'addresstype_id', 'addresstype_id');
}
}
型号Country.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Country extends Model
{
protected $table = 'country';
protected $primaryKey = 'country_id';
protected $keyType = 'int';
public $incrementing = true;
public $timestamps = false;
public function translation() {
return $this->hasOne('translations', 'translations_id', 'translations_id');
}
public function addressbook() {
return $this->belongsTo('address', 'country_id', 'country_id');
}
}
型号地址类型
namespace App;
use Illuminate\Database\Eloquent\Model;
class AddressType extends Model
{
protected $table = 'addresstype';
protected $primaryKey = 'addresstype_id';
protected $keyType = 'int';
public $incrementing = true;
public $timestamps = false;
public function translation() {
return $this->hasOne('translations', 'translations_id', 'translations_id');
}
public function addressbook() {
return $this->belongsTo('address', 'addresstype_id', 'addresstype_id');
}
}
型号Translation.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Translation extends Model
{
protected $table = 'translations';
protected $primaryKey = 'translations_id';
protected $keyType = 'int';
public $incrementing = true;
public $timestamps = false;
public function country() {
return $this->belongsTo('country', 'translations_id', 'translations_id');
}
public function addresstype() {
return $this->belongsTo('addresstype', 'translations_id', 'translations_id');
}
}
请求“$entries = AB::all();”一般工作,但我得到了 id,也许我在这里完全错了,但我认为来自外键的数据将被相应的模型替换(如果配置正确)。所以我的问题是:
一个。我是不是在配置过程中犯了错误,如果是,具体错误在哪里?
或
b.我用对象替换 id 的假设是完全错误的吗?
提前致谢!
史蒂夫
Laravel Eloquent 模型不会用关系数据替换活动记录的外键,它只会附加一个新的 属性 与相关方法同名classes 并且在那个 属性 中它放置了结果查询的所有模型实例,只有当您访问 属性 时,这才称为预加载。
It is explained here (Ofiicial Documentation)
$addressBook = App\AddressBook::find(1); //this only will return the active record with the id 1 and nothig more.
$addressBook->country; // The property "country" does not exist in the AddressBook Classs but eloquent models will return a "fake" property with the value of the result of the query by the method with the same name (only if the method returns an Eloquent Relation).
这种 Eloquent 行为是自然的,是一种非常巧妙的减少查询次数的方法,如果没有必要,Eloquent 永远不会加载关系。
如果您想在一组模型中加载关系,同时这些模型正在从数据库中检索,您需要明确指定要加载的关系。
$addressBook = App\AddressBook::with(['country', 'addresstype', 'anotherRelation'])->get(); // this will retrive all the addressBook models and in each one will attach the relations specified.
[编辑]
此外,您还必须将相关模型 class 的整个命名空间放在关系方法中,因此您需要替换为:
class Translation extends Model
{
protected $table = 'translations';
protected $primaryKey = 'translations_id';
protected $keyType = 'int';
public $incrementing = true;
public $timestamps = false;
// ****** You need to put the entire namespace of the Model class
public function country() {
return $this->belongsTo('App\Country', 'translations_id', 'translations_id');
}
我对 Laravel 很陌生,现在我正在尝试将以前的应用程序的一部分从一个小型的自写框架移动到 Laravel 中。地址簿是多语言的,因此 table 结构稍微复杂一些。
db-structure
这是我的源代码:
- AddressBookController.php
namespace App\Http\Controllers;
use App\AddressBook as AB;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
class AddressBookController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$entries = AB::all();
return view('addressBook')->with([
'class' => __CLASS__,
'function' => __FUNCTION__,
'line' => __LINE__,
'entries' => $entries,
]);
}
}
型号AddressBook.php
namespace App; use Illuminate\Database\Eloquent\Model; class AddressBook extends Model { protected $table = 'address'; protected $primaryKey = 'address_id'; protected $keyType = 'int'; public $incrementing = true; public $timestamps = false; protected $searchable = [ 'columns' => [ 'address.address_surname' => 10, 'address.address_company' => 5, 'address.address_vatid' => 2, ], ]; public function country() { return $this->hasOne('country', 'country_id', 'country_id'); } public function addresstype() { return $this->hasOne('addresstype', 'addresstype_id', 'addresstype_id'); } }
型号Country.php
namespace App; use Illuminate\Database\Eloquent\Model; class Country extends Model { protected $table = 'country'; protected $primaryKey = 'country_id'; protected $keyType = 'int'; public $incrementing = true; public $timestamps = false; public function translation() { return $this->hasOne('translations', 'translations_id', 'translations_id'); } public function addressbook() { return $this->belongsTo('address', 'country_id', 'country_id'); } }
型号地址类型
namespace App; use Illuminate\Database\Eloquent\Model; class AddressType extends Model { protected $table = 'addresstype'; protected $primaryKey = 'addresstype_id'; protected $keyType = 'int'; public $incrementing = true; public $timestamps = false; public function translation() { return $this->hasOne('translations', 'translations_id', 'translations_id'); } public function addressbook() { return $this->belongsTo('address', 'addresstype_id', 'addresstype_id'); } }
型号Translation.php
namespace App; use Illuminate\Database\Eloquent\Model; class Translation extends Model { protected $table = 'translations'; protected $primaryKey = 'translations_id'; protected $keyType = 'int'; public $incrementing = true; public $timestamps = false; public function country() { return $this->belongsTo('country', 'translations_id', 'translations_id'); } public function addresstype() { return $this->belongsTo('addresstype', 'translations_id', 'translations_id'); } }
请求“$entries = AB::all();”一般工作,但我得到了 id,也许我在这里完全错了,但我认为来自外键的数据将被相应的模型替换(如果配置正确)。所以我的问题是:
一个。我是不是在配置过程中犯了错误,如果是,具体错误在哪里?
或
b.我用对象替换 id 的假设是完全错误的吗?
提前致谢! 史蒂夫
Laravel Eloquent 模型不会用关系数据替换活动记录的外键,它只会附加一个新的 属性 与相关方法同名classes 并且在那个 属性 中它放置了结果查询的所有模型实例,只有当您访问 属性 时,这才称为预加载。
It is explained here (Ofiicial Documentation)
$addressBook = App\AddressBook::find(1); //this only will return the active record with the id 1 and nothig more.
$addressBook->country; // The property "country" does not exist in the AddressBook Classs but eloquent models will return a "fake" property with the value of the result of the query by the method with the same name (only if the method returns an Eloquent Relation).
这种 Eloquent 行为是自然的,是一种非常巧妙的减少查询次数的方法,如果没有必要,Eloquent 永远不会加载关系。
如果您想在一组模型中加载关系,同时这些模型正在从数据库中检索,您需要明确指定要加载的关系。
$addressBook = App\AddressBook::with(['country', 'addresstype', 'anotherRelation'])->get(); // this will retrive all the addressBook models and in each one will attach the relations specified.
[编辑] 此外,您还必须将相关模型 class 的整个命名空间放在关系方法中,因此您需要替换为:
class Translation extends Model
{
protected $table = 'translations';
protected $primaryKey = 'translations_id';
protected $keyType = 'int';
public $incrementing = true;
public $timestamps = false;
// ****** You need to put the entire namespace of the Model class
public function country() {
return $this->belongsTo('App\Country', 'translations_id', 'translations_id');
}