【问题标题】:Eloquent Model relationship does not return sub-relationship specific column valueEloquent 模型关系不返回子关系特定的列值
【发布时间】:2021-07-11 19:12:44
【问题描述】:

当产品名称等于“糟糕”时,我试图实现拉取用户信息和产品详细信息(指定昵称和名称),但我不知道为什么 getProducts 不返回任何东西。

用户模型

 public function getProducts(){
        return $this->hasMany('App\Models\Product','users_id');
    }

产品型号

public function users(){
        return $this->belongsTo(User::class);
    }

拉取数据的代码:

$products = User::with(['getProducts' => function($query){
            $query->select("users_id","name","nickname");
        }])->get();

当前输出:

"data": [
    {
      "id": 1,
      "name": "John Smith",
      "email": "john.smith@hotmail.com",
      "email_verified_at": null,
      "created_at": "2021-04-08T13:29:13.000000Z",
      "updated_at": "2021-04-08T13:29:13.000000Z",
      "role": 0,
      "get_products": [
        
      ]
    },
    {
      "id": 2,
      "name": "Kelvin Ooi",
      "email": "kelvin.ooi@hotmail.com",
      "email_verified_at": null,
      "created_at": "2021-04-08T13:29:13.000000Z",
      "updated_at": "2021-04-13T12:07:11.000000Z",
      "role": 1,
      "get_products": [
            {
                "nickname":"MCD",
                "name":"Oops"
            },
            {
                "nickname":"Mary Brown",
                "name":"Oops"
            },
            {
                "nickname":"Kentucy",
                "name":"KFC"
            },
            {
                "nickname":"Texas Chicken",
                "name":"TXS"
            }            
      ]
    }
  ]

预期输出

"data": [
    {
      "id": 1,
      "name": "John Smith",
      "email": "john.smith@hotmail.com",
      "email_verified_at": null,
      "created_at": "2021-04-08T13:29:13.000000Z",
      "updated_at": "2021-04-08T13:29:13.000000Z",
      "role": 0,
      "get_products": [
        
      ]
    },
    {
      "id": 2,
      "name": "Kelvin Ooi",
      "email": "kelvin.ooi@hotmail.com",
      "email_verified_at": null,
      "created_at": "2021-04-08T13:29:13.000000Z",
      "updated_at": "2021-04-13T12:07:11.000000Z",
      "role": 1,
      "get_products": [
            {
                "nickname":"MCD",
                "name":"Oops"
            },
            {
                "nickname":"Mary Brown",
                "name":"Oops"
            }
      ]
    }
  ]

【问题讨论】:

  • 我认为你需要包含user_id(外键),所以$query->select('user_id', 'name', 'nickname');,否则它不知道如何加载它们。
  • 我已经检查了我的数据库已经有外键关系但它仍然无法正常工作..
  • 如果我想拉取产品名称为“糟糕”的用户怎么办 $products = User::with(['getProducts' => function($query){ $query- >select("users_id","name","nickname"); }])->where("products.name","Oops")->get();
  • 但它不起作用..
  • 所以我刚刚用我的本地模型/关系测试了你的代码,它可以工作:Model::with(['relationship' => function($q){ $q->select('id', 'relation_id', 'column'); }])->find(1); 这将返回 ID 为 1 的模型,以及与这 3 列的关系记录。您的代码应该可以正常工作...

标签: php mysql laravel eloquent eloquent-relationship


【解决方案1】:

getProducts 不是一个好的关系名称,我们直接称它为products

public function products()
{
    return $this->hasMany('App\Models\Product','users_id');
}

注释中的代码不起作用,因为您在主查询中指定了 where 子句,而不是子查询。

return User::with(['products' => function ($query) { 
    $query->select("users_id","name","nickname"); 
}])
// This got to be in the sub query.
->where("products.name","Oops")
->get();

所以让我们将您的代码更新为:

$productName = 'Oops';

return User::with(['products' => function ($query) use ($productName) { 
    $query->select("users_id","name","nickname", "price")
        ->where("name","LIKE", "%{$productName}%"); 
}])
->get();

我已经看到您对此答案的评论。让我们为 User 模型定义一个 total custom attribute

class User extends Model
{
    protected $appends = ['total'];

    public function getTotalAttribute()
    {
        // This is higher order message, if you haven't used it: https://laravel.com/docs/8.x/collections#higher-order-messages
        return $this->products->sum->price;
    }
}

那么total 属性将成为任何用户的一部分。

【讨论】:

  • 如果我想总结产品价格并显示产品详细信息,如图所示:ibb.co/3hpb8Qx 我尝试添加“->addSelect("DB::raw("SELECT SUM( p.price) FROM products AS p WHERE p.id = products.id")") 在最后的 get() 之前,但它仍然给我一个错误。
  • @MiracleHades 那行不通。主查询不知道 products 表。 with 方法中的查询是对主要查询的单独查询。我已经更新了我的答案。
  • 除此之外,如果我想从模型实例中选择 id、email 和 name 作为全名。我试图在 with() 之前使用 pluck() 但我没有运气让它工作..
  • 我遇到了另一个问题,我不知道为什么我什至没有包含 with('products') 时,产品集合仍然跟随我。可执行代码为 $ttl = User::find(1)->first();
  • 它应该只返回普通用户集合而不是用户组合产品集合...
猜你喜欢
  • 1970-01-01
  • 2019-09-20
  • 1970-01-01
  • 2021-08-22
  • 2015-10-29
  • 2016-02-26
  • 2017-01-29
  • 2014-11-22
  • 1970-01-01
相关资源
最近更新 更多