Laravel Eloquent ORM 关系查询

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24545381/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 09:45:11  来源:igfitidea点击:

Laravel Eloquent ORM relationship query

laraveleloquent

提问by olleh

I need help, I have a problem with querying Model Relationships. I actually know and get the job done using the query method but I'd like to know the "laravel way" of querying relationships.

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

Here's what's on my controller. //HealthProfile Controller //$id value is 2

这是我的控制器上的内容。//HealthProfile Controller //$id 值为2

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

problem is that the return for the query is the records for id = 1 and not id = 2. It basically ignored the "find" method. I just want to get the health profiles for a specific user_id.

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

[id] => 1
    [firstname] => patrick
    [lastname] => marino
    [email] => [email protected]
    [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
                )

This is my schema //User model

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

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

//HealthProfile model

//健康档案模型

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

采纳答案by olleh

I've found the culprit. L4 has problems with snake cased methods! I changed it to camelCase and it worked.

我找到了罪魁祸首。L4 有蛇套方法的问题!我将其更改为驼峰式大小写并且它起作用了。

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

src: https://coderwall.com/p/xjomzg

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

回答by Jarek Tkaczyk

First a few words of explanation:

首先解释几句:

find($id)already runs the query (it uses where(id, $id)->first()under the hood) so place it at the end, because now you unwittingly did this:

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

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

Another problem is, like you already noticed, that Eloquentwon't work with this setup:

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

public function health_profiles() ...

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

because when loading dynamic properties (relations) it looks for camelCased method on the model.

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

However eager loading willwork as expected:

然而,急切加载将按预期工作:

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

So you definitely should comply with the naming conventions if you want Eloquentto be your friend ;)

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



But that's not all. It will work the other way around:

但这还不是全部。它会反过来工作:

public function healthProfiles() ...

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


To sum up and answer your question, each of those will work for you:

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

// 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();

回答by lagbox

You can try putting the withbefore the findso that the builder knows to eager load that relationship on what you are trying to find.

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

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

回答by olleh

Try this

尝试这个

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

I don't think you need to call the firstmethod because findas it's stated will only find the one row of data that you need.

我认为您不需要调用该first方法,因为find正如它所说的那样只会找到您需要的一行数据。