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

Add @upsert directive and nested mutation operations to create or update a model regardless whether it exists #1005

Merged
merged 32 commits into from Oct 15, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
2c5caf4
Partial upsert implementation with BelongToMany test
Oct 11, 2019
1ca2119
Fix StyleCI
Oct 11, 2019
c5447c4
Fix PHPDoc
Oct 11, 2019
2e44268
Add info to unreleased section of the changelog
Oct 11, 2019
6c5f541
BelongsToMany upsert ready
Oct 11, 2019
24da674
BelongsTo upsert ready
Oct 11, 2019
0ae0d53
Add HasMany to upsert
Oct 11, 2019
f2d599b
Fix StyleCI
Oct 11, 2019
583b239
Add HasOne to upsert
Oct 12, 2019
feace74
Add missing tests
Oct 12, 2019
68a2e5d
Add MorphToMany to upsert
Oct 12, 2019
a075834
Add MorphOne to upsert
Oct 12, 2019
80bc88f
Add MorphToMany to upsert
Oct 12, 2019
7da6681
Add MorphTo to upsert
Oct 12, 2019
dc7d87b
Add documentation
Oct 12, 2019
869622b
Add documentation to v4.4
Oct 12, 2019
7456e8c
Update CHANGELOG.md
joskfg Oct 12, 2019
f579c05
Remove @upsert from 4.4.0 docs
Oct 12, 2019
e307b58
Fix StyleCI
Oct 12, 2019
b48d1a6
Refactor upsert and update
Oct 13, 2019
87eec45
Refactor Create/Update/Upsert directives to DRY
Oct 13, 2019
5e4d232
Fix StyleCI
Oct 13, 2019
38ea803
Upgade documentation to be more clear
Oct 13, 2019
1d12f1b
Improve executeUpsert check
Oct 14, 2019
ea87ded
Fix StyleCI
Oct 14, 2019
8d78822
Fix issue when creating without autoincrement key
Oct 14, 2019
5be34ff
Remove unneeded code from directives
spawnia Oct 14, 2019
85dcd3a
Reorder and comment the MutationExecutor
spawnia Oct 14, 2019
230b95d
Some wording in the docs
spawnia Oct 14, 2019
174464f
Fix syntax
spawnia Oct 14, 2019
cc9fb65
Force different ids in upsert to check that it actually uses it
Oct 15, 2019
8a53ace
Update CHANGELOG.md
spawnia Oct 15, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
27 changes: 5 additions & 22 deletions src/Schema/Directives/CreateDirective.php
Expand Up @@ -5,36 +5,14 @@
use Illuminate\Support\Collection;
use Illuminate\Database\Eloquent\Model;
use Nuwave\Lighthouse\Execution\MutationExecutor;
use Illuminate\Database\Eloquent\Relations\Relation;

class CreateDirective extends MutationExecutorDirective
{
/**
* Name of the directive.
*
* @return string
*/
public function name(): string
{
return 'create';
}

/**
* Execute a create mutation.
*
* @param \Illuminate\Database\Eloquent\Model $model
* An empty instance of the model that should be created
* @param \Illuminate\Support\Collection $args
* The corresponding slice of the input arguments for creating this model
* @param \Illuminate\Database\Eloquent\Relations\Relation|null $parentRelation
* If we are in a nested create, we can use this to associate the new model to its parent
* @return \Illuminate\Database\Eloquent\Model
*/
protected function executeMutation(Model $model, Collection $args, ?Relation $parentRelation = null): Model
{
return MutationExecutor::executeCreate($model, $args, $parentRelation);
}

public static function definition(): string
{
return /* @lang GraphQL */ <<<'SDL'
Expand All @@ -50,4 +28,9 @@ public static function definition(): string
) on FIELD_DEFINITION
SDL;
}

protected function executeMutation(Model $model, Collection $args): Model
{
return MutationExecutor::executeCreate($model, $args);
}
}
31 changes: 25 additions & 6 deletions src/Schema/Directives/MutationExecutorDirective.php
Expand Up @@ -8,14 +8,15 @@
use Illuminate\Database\DatabaseManager;
use Nuwave\Lighthouse\Schema\Values\FieldValue;
use Nuwave\Lighthouse\Support\Contracts\GlobalId;
use Illuminate\Database\Eloquent\Relations\Relation;
use Nuwave\Lighthouse\Support\Contracts\FieldResolver;
use Nuwave\Lighthouse\Support\Contracts\GraphQLContext;
use Nuwave\Lighthouse\Support\Contracts\DefinedDirective;

abstract class MutationExecutorDirective extends BaseDirective implements FieldResolver, DefinedDirective
{
/**
* The database manager.
*
* @var \Illuminate\Database\DatabaseManager
*/
protected $databaseManager;
Expand Down Expand Up @@ -50,20 +51,38 @@ public function resolveField(FieldValue $fieldValue): FieldValue
{
return $fieldValue->setResolver(
function ($root, array $args, GraphQLContext $context, ResolveInfo $resolveInfo): Model {
$modelClass = $this->getModelClass();
/** @var \Illuminate\Database\Eloquent\Model $model */
$model = new $modelClass;
$model = new ($this->getModelClass());

$executeMutation = function () use ($model, $args): Model {
return $this->executeMutation($model, new Collection($args))->refresh();
return $this
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer this indentation

->executeMutation(
$model,
new Collection($args)
)
->refresh();
};

return config('lighthouse.transactional_mutations', true)
? $this->databaseManager->connection($model->getConnectionName())->transaction($executeMutation)
? $this
->databaseManager
->connection(
$model->getConnectionName()
)
->transaction($executeMutation)
: $executeMutation();
}
);
}

abstract protected function executeMutation(Model $model, Collection $args, ?Relation $parentRelation = null): Model;
/**
* Execute a mutation on a model.
*
* @param \Illuminate\Database\Eloquent\Model $model
* An empty instance of the model that should be mutated.
* @param \Illuminate\Support\Collection $args
* The corresponding slice of the input arguments for mutating this model.
* @return \Illuminate\Database\Eloquent\Model
*/
abstract protected function executeMutation(Model $model, Collection $args): Model;
}
27 changes: 5 additions & 22 deletions src/Schema/Directives/UpdateDirective.php
Expand Up @@ -5,36 +5,14 @@
use Illuminate\Support\Collection;
use Illuminate\Database\Eloquent\Model;
use Nuwave\Lighthouse\Execution\MutationExecutor;
use Illuminate\Database\Eloquent\Relations\Relation;

class UpdateDirective extends MutationExecutorDirective
{
/**
* Name of the directive.
*
* @return string
*/
public function name(): string
{
return 'update';
}

/**
* Execute an update mutation.
*
* @param \Illuminate\Database\Eloquent\Model $modelInstance
* An empty instance of the model that should be updated
* @param \Illuminate\Support\Collection $args
* The corresponding slice of the input arguments for updating this model
* @param \Illuminate\Database\Eloquent\Relations\Relation|null $parentRelation
* If we are in a nested update, we can use this to associate the new model to its parent
* @return \Illuminate\Database\Eloquent\Model
*/
protected function executeMutation(Model $model, Collection $args, ?Relation $parentRelation = null): Model
{
return MutationExecutor::executeUpdate($model, new Collection($args))->refresh();
}

public static function definition(): string
{
return /* @lang GraphQL */ <<<'SDL'
Expand All @@ -56,4 +34,9 @@ public static function definition(): string
) on FIELD_DEFINITION
SDL;
}

protected function executeMutation(Model $model, Collection $args): Model
{
return MutationExecutor::executeUpdate($model, $args);
}
}
28 changes: 5 additions & 23 deletions src/Schema/Directives/UpsertDirective.php
Expand Up @@ -5,37 +5,14 @@
use Illuminate\Support\Collection;
use Illuminate\Database\Eloquent\Model;
use Nuwave\Lighthouse\Execution\MutationExecutor;
use Illuminate\Database\Eloquent\Relations\Relation;

class UpsertDirective extends MutationExecutorDirective
{
/**
* Name of the directive.
*
* @return string
*/
public function name(): string
{
return 'upsert';
}

/**
* Execute an upsert mutation.
*
* @param \Illuminate\Database\Eloquent\Model $model
* An empty instance of the model that should be created or updated
* @param \Illuminate\Support\Collection $args
* The corresponding slice of the input arguments for creating or updating this model
* @param \Illuminate\Database\Eloquent\Relations\Relation|null $parentRelation
* If we are in a nested upsert, we can use this to associate the new model to its parent
*
* @return \Illuminate\Database\Eloquent\Model
*/
protected function executeMutation(Model $model, Collection $args, ?Relation $parentRelation = null): Model
{
return MutationExecutor::executeUpsert($model, new Collection($args))->refresh();
}

public static function definition(): string
{
return /* @lang GraphQL */ <<<'SDL'
Expand All @@ -57,4 +34,9 @@ public static function definition(): string
) on FIELD_DEFINITION
SDL;
}

protected function executeMutation(Model $model, Collection $args): Model
{
return MutationExecutor::executeUpsert($model, $args);
}
}