【问题标题】:Laravel Eloquent ORM relationship queryLaravel Eloquent ORM 关系查询
【发布时间】:2014-07-03 05:11:16
【问题描述】:

我需要帮助,我在查询模型关系时遇到问题。 我实际上知道并使用查询方法完成了工作,但我想知道查询关系的“laravel 方式”。

这是我的控制器上的内容。 //健康档案控制器 //$id 值为 2

$health_profiles = User::find($id)->with('health_profiles')->first();

问题是查询的返回是id = 1而不是id = 2的记录。它基本上忽略了“find”方法。我只想获取特定 user_id 的健康档案。

[id] => 1
    [firstname] => patrick
    [lastname] => marino
    [email] => patrick@gmail.com
    [membership_code] => starpatrick
    [birthdate] => 1989-05-17
    [contact_number] => 1230123
    [active] => 1
    [created_at] => 2014-07-01 16:10:05
    [updated_at] => 2014-07-01 16:10:05
    [remember_token] => 
    [health_profiles] => Array
        (
            [0] => Array
                (
                    [id] => 1
                    [user_id] => 1
                    [parent_id] => 
                    [name] => patrick star
                    [relationship] => 
                    [gender] => male
                    [birthdate] => 1989-05-17
                    [marital_status] => 
                    [number_of_children] => 
                    [weigth] => 
                    [height] => 
                    [blood_type] => 
                    [blood_pressure] => 
                    [hdl] => 
                    [ldl] => 
                    [vldl] => 
                    [visual_activity] => 
                    [lifestyle] => 
                    [current_bmi] => 
                    [weight_goal] => 
                    [weekly_goal] => 
                    [rdc] => 
                    [created_at] => 2014-07-01 16:10:05
                    [updated_at] => 2014-07-01 16:10:05
                )

这是我的架构 //用户模型

   public function health_profiles()
        {
            return $this->hasMany('HealthProfile');        
        }

//健康档案模型

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

【问题讨论】:

    标签: laravel eloquent


    【解决方案1】:

    先解释几句:

    find($id) 已经运行了查询(它在后台使用where(id, $id)->first())所以把它放在最后,因为现在你不知不觉地这样做了:

    User::find($id);
    User::with('health_profiles')->first();
    

    另一个问题是,正如您已经注意到的那样,Eloquent 不适用于此设置:

    public function health_profiles() ...
    
    $user = User::find($id);
    $user->health_profiles; // null
    

    因为在加载动态属性(关系)时,它会在模型​​上查找 camelCased 方法。

    但是急切加载按预期工作:

    $user = User::with('health_profiles')->find($id);
    $user->health_profiles; // related model/collection
    

    所以如果你想让Eloquent 成为你的朋友,你绝对应该遵守命名约定;)


    但这还不是全部。反之亦然:

    public function healthProfiles() ...
    
    $user = User::find($id);
    $user->healthProfiles; // works, returns related model/collection
    $user->health_profiles; // works as well, returns the model/collection
    

    总结并回答您的问题,每一个都适合您:

    // Assuming Profile is the model
    
    // 2 queries
    $user = User::find($id);
    $profiles = $user->healthProfiles;
    
    // or 1 query
    $profiles = Profile::where('user_id', $id)->get();
    
    // or 2 queries: 1 + 1 subquery
    $profiles = Profile::whereHas('user', function ($q) use ($id) {
       $q->where('users.id', $id);
    })->get();
    

    【讨论】:

    • 感谢@deczo的详细解释!
    【解决方案2】:

    您可以尝试将with 放在find 之前,以便构建器知道急切地将这种关系加载到您要查找的内容上。

    $user = User::with('health_profiles')->find($user_id);
    $health_profiles = $user->health_profiles;
    

    【讨论】:

    • 谢谢!这也有效,但我只需要 health_profile 数据,这样做也会返回用户模型数据,这对我的方法来说是一种过度杀伤。谢谢!
    • 如果你愿意,我可以向你展示从另一个方向实现这一目标的方法。
    • 请分享。这是我的方法 $user = User::where('id', '=', $id)->first(); $user->healthProfiles->toArray();
    • 如果您查看 deczo 的回答,最后一个示例是我建议的另一种方式。
    【解决方案3】:

    试试这个

    User::with('health_profiles')->find($id);
    

    我认为您不需要调用first 方法,因为find 如上所述只会找到您需要的一行数据。

    【讨论】:

    • 谢谢!这个方法也有效!但是,问题是它还返回了用户属性以及 HealthProfiles,这对于我的需要来说太多了。你实际上是对的,如果你先链接它会返回错误的用户 ID 记录。
    • 试试$user->healthProfiles。这会将返回的数据缩小到仅健康档案
    • 嘿伙计!这就是我实际所做的!无论如何,我如何过滤我的 healthProfiles 以仅返回具有“parent_id”= null 的记录
    • 你可以试试$user->health_profiles()->where('parent_id', '=', 'null');
    【解决方案4】:

    我找到了罪魁祸首。 L4 有蛇壳方法的问题!我将其更改为 camelCase 并且有效。

    $lawly = User::where('id', '=', 2)->first();
    $lawly->healthProfiles->toArray()
    

    源代码:https://coderwall.com/p/xjomzg

    【讨论】:

    • 甜美的,好看的......而且你真的不需要在单个模型上使用急切加载,所以我很高兴看到你删除了它。 :)
    猜你喜欢
    • 2015-01-21
    • 2015-04-09
    • 1970-01-01
    • 1970-01-01
    • 2017-03-16
    • 2013-10-03
    • 2017-07-19
    • 1970-01-01
    • 2021-09-25
    相关资源
    最近更新 更多