【问题标题】:Has many through with pivot table in Laravel4在 Laravel4 中通过数据透视表进行了许多操作
【发布时间】:2026-01-19 04:55:01
【问题描述】:

我正在尝试与 Eloquent 建立 hasManyTrough 关系,但从文档中不清楚它是如何工作的。

表格:

users
   - id
   - firstname
   - ...etc

accounts
   - id
   - user_id
   - username
   - ...etc

roles
   - id
   - permissions

account_role
   - id
   - account_id
   - role_id

模型

<?php
class User extends Eloquent {

    public function account()
    {
        return $this->hasOne('Account');
    }

    // This is what I'm trying to achieve
    public function roles()
    {
        return $this->hasManyThrough('Role', 'Account');
    }
}

class Role extends Eloquent {

    public function accounts()
    {
        return $this->belongsToMany('Account')->withTimestamps();
    }
}

class Account extends Eloquent {

    public function user()
    {
        return $this->belongsTo('User');
    }
}

错误和问题 我得到的错误是: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'roles.account_id' in 'on clause'

我知道我可以做某事$user-&gt;account-&gt;roles,但我希望能够做某事$user-&gt;roles。如何正确设置?

【问题讨论】:

  • hasManyThrough 不适用于多对多关系,请查看此答案:*.com/questions/23788844/…。如果您仍有疑问,请随时提问。
  • 不错的解决方法,但我需要预先加载才能使用 User 模型。也许有一个解决方案来定义我自己的Relation 或其他东西。不过不知道该怎么做。
  • 当然你可以扩展 Eloquent 并创建自定义关系、模型方法和其他东西。这取决于你,我链接的答案应该让你知道如何做到这一点。我对 belongsToThrough 做的完全一样。

标签: laravel laravel-4 eloquent


【解决方案1】:

最后,我通过以下方式解决了这个问题:

class User extends Eloquent {

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function roles()
    {
        return $this->account->belongsToMany('Navicula\Entities\Role');
    }
}

我怀疑这不会急切加载帐户,从而导致大量查询开销。但是,当我使用 User::with('roles')-&gt;limit(100)-&gt;get(); 尝试并记录查询时,会运行以下查询:

SELECT * FROM `users` WHERE `users`.`deleted_at` IS NULL LIMIT 100
SELECT * FROM `accounts` WHERE `accounts`.`deleted_at` IS NULL LIMIT 1
SELECT `roles`.*, `account_role`.`account_id` as `pivot_account_id`, `account_role`.`role_id` as `pivot_role_id` FROM `roles` inner join `account_role` on `roles`.`id` = `account_role`.`role_id` WHERE `account_role`.`account_id` in ('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '60', '61', '62', '63', '64', '65', '67', '68', '70', '71', '72', '73', '74', '75', '78', '79', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '100', '101', '102', '103', '104', '105', '106')

这正是我们想要的。谢谢泰勒 ;-)

【讨论】: