Laravel 5仅选择hasMany关系上的关系数据 [英] Laravel 5 select only relationship data on hasMany relationship

查看:351
本文介绍了Laravel 5仅选择hasMany关系上的关系数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个具有projects的应用程序,而项目具有plot_types.

I am building an application that has projects and projects have plot_types.

我希望能够检查当前项目下是否存在plot_type.

I want to be able to check if a plot_type exists under the current project.

我有以下代码:

$testResult = $project->with(['plotTypes' => function($query) use ($row) {
            $query->where('name', $row->plot_name);
        }])->first()

这将产生以下MySQL:

This produces the following MySQL:

select exists(select * from `projects` where exists (select * from `projects_plot_types` where `projects_plot_types`.`project_id` = `projects`.`id` and `name` = ?)) as `exists`

此SQL返回与$project对象不相关的行.例如,当我执行dd($project)时,我得到:

This SQL returns rows that are NOT related to the $project object. For example when I do dd($project) I get:

#attributes: array:11 [▼
    "id" => "4"
    "name" => "xxx"
    "number" => "1234"
    "builder" => "1"
    "overall_budget" => "3456.00"
    "start_date" => "2016-03-31"
    "end_date" => "2016-04-30"
    "created_date" => "2016-03-16 15:22:05"
    "updated_date" => "2016-03-16 15:22:07"
  ]

但是,当我执行dd($testResult);时,它给出了;

Yet, when I do dd($testResult); it gives;

#relations: array:1 [▼
"plotTypes" => Collection {#767 ▼
  #items: array:1 [▼
    0 => ProjectsPlotTypes {#770 ▼
      #table: "projects_plot_types"
      #fillable: array:2 [▶]
      +timestamps: false
      #connection: null
      #primaryKey: "id"
      #perPage: 15
      +incrementing: true
      #attributes: array:4 [▼
        "id" => "1"
        "project_id" => "1"
        "name" => "TYPE 1  - VENTILATION"
        "budget" => "324.67"
      ]

注意,上面的project_id显示为1.这与当前项目无关,因为当前项目ID为4.

Notice, the project_id above shows 1. This is not related to the current project as the current project id is 4.

为什么会这样?

推荐答案

这是ActiveRecord模型中那些可能造成混淆的部分之一.您所有的模型实例都包含用于检索模型实例的相同方法,因此,很容易想到某些事情在实际上不起作用时应该以一种方式起作用.

This is one of those potentially confusing parts of the ActiveRecord model. All your model instances contain the same methods used to retrieve model instances, so it easy think something should work one way when it really doesn't.

调用$project->with(),与调用Project::with()完全相同.即使在项目的实例上调用with(),也不会将加载的对象限制为仅与实例相关的对象.

Calling $project->with(), this is the exact same as calling Project::with(). Even though you're calling with() on an instance of the project, it isn't going to restrict the loaded objects to only those related to your instance.

调用$project->with()时,首先要做的是为所有项目创建一个新查询,然后添加急切加载.然后,您调用first(),它将仅获取第一个项目记录及其所有急切加载的对象.

When you call $project->with(), the first thing it does is create a new query for all projects, and then adds in the eager loading. You then call first(), which just gets the first project record, and all its eager loaded objects.

要获取特定项目的图类型,您有几个选择.

To get the plot types for your specific project, you have a couple options.

  1. 只需查询关系. $project->plotTypes()为您提供与项目关联的所有绘图类型的基本查询.您可以添加约束并从那里获取记录.

  1. Just query the relationship. $project->plotTypes() gives you a base query for all the plot types associated with your project. You can add your constraints and get the records from there.

$plotTypes = $project->plotTypes()->where('name', $row->plot_name)->get();
dd($plotTypes);

  • 使用约束加载相关的图类型:

  • Load the related plot types with constraints:

    // assume your project doesn't have any plottypes loaded yet
    $project = Project::find(1);
    
    // load the plottypes relation with constraints
    $project->load(['plotTypes' => function($query) use ($row) {
        $query->where('name', $row->plot_name);
    }]);
    dd($project->plotTypes);
    

  • 过滤已加载的相关图类型的Collection. $project->plotTypes具有与项目相关的所有绘图类型,但是您可以在Collection上使用where()方法(与查询中的where()不同)来过滤Collection中的记录. /p>

  • Filter the already loaded Collection of related plot types. $project->plotTypes has all the plot types related to your project, but you can use the where() method on the Collection (different than the where() on the query) to filter through the records in the Collection.

    // assume your project already has all plotTypes loaded
    $project = Project::with('plotTypes')->find(1);
    
    // you just want to get a subset of those pre-loaded plottypes
    $plotTypes = $project->plotTypes->where('name', $row->plot_name);
    dd($plotTypes);
    

  • 这篇关于Laravel 5仅选择hasMany关系上的关系数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆