Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.6] Add Collection::loadMissing() #24166

Merged
merged 2 commits into from
May 14, 2018
Merged

[5.6] Add Collection::loadMissing() #24166

merged 2 commits into from
May 14, 2018

Conversation

staudenmeir
Copy link
Contributor

We currently have Model::loadMissing(), which can only handle non-nested relationships and doesn't fully support loading specific columns.

This PR adds Collection::loadMissing():

$posts = Post::with('comments')->get();
$posts->loadMissing('comments.parent');

The shortest way (I know) to achieve the same right now:

(new \Illuminate\Database\Eloquent\Collection($posts->pluck('comments')->collapse()))->load('parent');

Collection::loadMissing() fully supports nested relationships and loading specific columns. There's no support for closures yet (Model::loadMissing() doesn't support closures either).

We can use it to bring the same features to Model::loadMissing().

I added integration tests for both methods.

Fixes #23027 and #24121.

@bepsvpt
Copy link
Contributor

bepsvpt commented May 24, 2018

This pull request is breaking change.

Before this pull request, when loading relation with ambiguous column name, we can use dot to specific table name of the ambiguous column.

How to reproduce:

Assume there are User and Role two models and their relation is many-to-many.

User::create();
Role::create();

User::first()->roles()->attach(Role::first());

User::first()->loadMissing('roles:id'); // this will cause `ambiguous column name: id`

// Before this pull request, we can use roles.id to fix this problem.
// However, after this pull request, it will result in `RelationNotFoundException`
User::first()->loadMissing('roles:roles.id'); 

db46f64

db46f64

27b1652

27b1652


users, roles and role_user table migrations

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
}
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateRolesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('roles', function (Blueprint $table) {
            $table->increments('id');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('roles');
    }
}
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateRoleUserTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('role_user', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('role_id')->unsigned();
            $table->integer('user_id')->unsigned();

            $table->unique(['role_id', 'user_id']);
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('role_user');
    }
}

user and role models

<?php

namespace App;

use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function roles()
    {
        return $this->belongsToMany(Role::class);
    }
}
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Role extends Model
{
    //
}

@staudenmeir
Copy link
Contributor Author

Sorry about that. Here's the fix: #24329

@bepsvpt
Copy link
Contributor

bepsvpt commented May 27, 2018

Thanks a lot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants