我在用户和承包商之间建立了多态关系:
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('first_name');
$table->string('last_name');
$table->morphs('user');
});
Schema::create('contractors', function (Blueprint $table) {
$table->bigIncrements('id');
//... etc
});
App \ User
public function userable()
{
return $this->morphTo();
}
App \ Contractor
public function user()
{
return $this->morphOne('App\User', 'userable');
}
目标是拥有不同的用户类型,因为承包商可能需要收集我们需要收集的其他字段数据,但他们将始终拥有用户表中的所有字段。
我遇到的问题是,在获取所有承包商并渴望加载用户数据时,如何按用户表中的last_name列进行排序?
class ContractorController extends Controller
{
public function all(Request $request)
{
return Contractor::with('user')->paginate(15); // order by users.last_name here
}
}
我已经读到我必须加入表,但是由于某种原因在响应中为用户对象返回NULL。
class ContractorController extends Controller
{
public function all(Request $request)
{
return Contractor::with('user')
->join('users', 'contractors.id', '=', 'users.userable_id')
->paginate(15);
}
}
因为lastname
是用户表的列。您不能使用with('user')
并不能按lastname
进行订购。
但是,您可以使用join('users',...)
代替with(user)
:
Contractor::join('users', 'contractors.id', '=', 'users.userable_id')
->orderBy('users.lastname')
->paginate(15);
并且由于在使用id(contractors.id, users.id)
时存在重复的join
,因此如果您仍想将user
对象作为属性,则可以这样进行:
Contractor::join('users', 'contractors.id', '=', 'users.userable_id')
->orderBy('users.lastname')
->selectRaw('contractors.*, users.lastname')
->with('user')
->paginate(15);