Laravel hasManyThrough 表的相同命名字段存在问题

Laravel hasManyThrough issue with same named field of tables

这些是我拥有的模型:

class User extends Eloquent
{
    public function categories()
    {
        return $this->hasMany('Category');
    }
    public function forms()
    {
        return $this->hasManyThrough('App\Models\Form', 'Category');
    }
}

class Category extends \Eloquent {
    public function user()
    {
        return $this->belongsTo('User');
    }
    public function forms()
    {
        return $this->hasMany('App\Models\Form');
    }
}

namespace App\Models;
class Form extends \Eloquent {
    public function category()
    {
        return $this->belongsTo('Category');
    }
}

现在我想通过它的 id 得到一个 Form 以便它确保 Form belongsTo 一个特定的 User.

所以我正在使用:

$form   = $user->forms()->find($id);

它工作正常,但这里有一个问题,它显示 Category.name 而不是显示 Form.name。我知道这是因为两个 table 都有名为 name 的字段。我可以更改字段名称,但这不是一个好的解决方案。

我怎样才能以最好的方式解决这个问题?

这是当前的解决方案:

$form   = $user->forms()->whereRaw('forms.id = ?', array($id))->get()->first();

这是使用 ->first() 的旧错误解决方案:

$form   = $user->forms()->find($id)->first();

我知道错误在哪里了。 find() 方法的第二个参数是要检索的列列表。如果您不传入此值,则默认为 "array(*)"。因此,当您执行 $user->forms()->find($id); 时,它会将原来的 select forms.*, categories.user_id ... 替换为 select * ...first() 方法也会发生这种情况。

get() 方法也会发生这种情况,但是 HasManyThrough 关系会覆盖 get() 方法,因此它会在选择所有内容时添加正确的 select 值"array(*)".

那么,您的解决方案应该可以正常工作。但是,您不需要 whereRaw; where 应该可以正常工作:

$forms = $user->forms()->where('forms.id', $id)->get();

获得 Collection 后,您可以安全地在 Collection 上使用 first(),因此您也可以这样做:

// first() on the Collection is fine; first() on the HasManyThrough relationship is not.
$form = $user->forms()->where('forms.id', $id)->get()->first();