diff --git a/CHANGELOG.md b/CHANGELOG.md index 643b6a4..352d454 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 4.1.0 +Adds support for quick create syntax, by using the `craft` method. This allows for a simpler +syntax when you only need to quickly create a model and don't need to add complex relationship mapping. + # 4.0.1 Adds backwards-compatible support for `snake_case` relationship methods. Poser will check to see if a `snake_case` method exists on the `Model` and call it if so, instead of the default `camelCase`. diff --git a/README.md b/README.md index 4f0ddb6..93927ca 100644 --- a/README.md +++ b/README.md @@ -596,6 +596,17 @@ instead call the relationship method statically, like so: `UserFactory::withCust Creates a new instance of the factory, but informs the factory that you will be creating multiple models. Use this to instantiate the class when you wish to create multiple entries in the database. +#### `::craft(int $count, ...$attributes)` +Allows you to create multiple models, persist them to the database, and return the resulting collection, all in one +method call. A very useful shortcut when you don't need complex relationship mapping. You may pass in the count of +models you wish to create, along with attributes that should be given to those models. + +#### `::craft(...$attributes, int $count)` +Alternate syntax for `craft` as described above, which more closely matches `factory` method baked into Laravel. + +#### `::craft(array $attributes = null)` +If you only need to craft one model, you can omit the count. It will return a single model instead of a collection. + #### `->create(...$attributes)` or `(...$attributes)` Similar to the Laravel factory `create` command, this will create the models, persisting them to the database. You may pass an associative array of column names with desired values, which will be applied to the diff --git a/src/Factory.php b/src/Factory.php index cebd236..ba206c2 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -4,6 +4,7 @@ namespace Lukeraymonddowning\Poser; use Closure; +use Illuminate\Support\Arr; use ReflectionClass; use ReflectionMethod; use Mockery\Exception; @@ -63,6 +64,37 @@ public static function times(int $count) return $factory; } + /** + * For those times where you don't need super complex relationship mapping, and just want to quickly build a model + * or collection of models. + * + * @param mixed ...$parameters If you need to build multiple models, the first or last parameter should be the + * desired count, with any other parameters forming your attribute sets. + * If you're building a single model, you may omit the count. + * + * @return \Illuminate\Database\Eloquent\Collection|Model|Model[]|Collection + */ + public static function craft(...$parameters) + { + $factory = self::new(); + + if (empty($parameters)) { + return $factory->create(); + } + + if (is_int($parameters[0])) { + $factory->count = Arr::pull($parameters, 0); + } + + if (is_int(Arr::last($parameters))) { + $factory->count = Arr::pull($parameters, count($parameters) - 1); + } + + $factory->withAttributes(...$parameters); + + return $factory->create(); + } + public function __construct() { $this->testCaseCaller = new TestCaseCaller(); @@ -320,8 +352,8 @@ public function afterCreating(Closure $closure) * Given an array of attribute sets, returns the desired set if available, else the first one available * either through looping or retrieving the first one, or an empty array. * - * @param array $attributes The array of arrays from which to extract an attribute set. - * @param int $desiredIndex The ideal index of the attribute set you would like + * @param array $attributes The array of arrays from which to extract an attribute set. + * @param int $desiredIndex The ideal index of the attribute set you would like * @return array|mixed */ protected function getDesiredAttributeData(array $attributes, int $desiredIndex) @@ -335,7 +367,7 @@ protected function getDesiredAttributeData(array $attributes, int $desiredIndex) /** * @param string $functionName - * @param array $arguments + * @param array $arguments * @return bool True if the relationship was handled, or false if it couldn't be handled. */ protected function handleRelationship(string $functionName, array $arguments) @@ -348,7 +380,7 @@ protected function handleRelationship(string $functionName, array $arguments) * Prepares a `with[RelationshipName]` by parsing it and storing it until the factory calls `create()`. * * @param string $functionName The name of the function that was called by the user. - * @param array $arguments The arguments that were passed to the function. + * @param array $arguments The arguments that were passed to the function. * @return bool True if the relationship was handled, else false. */ protected function handleWithRelationship(string $functionName, array $arguments) @@ -362,7 +394,7 @@ protected function handleWithRelationship(string $functionName, array $arguments * Prepares a `for[RelationshipName]` by parsing it and storing it until the factory calls `create()`. * * @param string $functionName The name of the function that was called by the user. - * @param array $arguments The arguments that were passed to the function. + * @param array $arguments The arguments that were passed to the function. * @return bool True if the relationship was handled, else false. */ protected function handleForRelationship(string $functionName, array $arguments) @@ -426,8 +458,8 @@ protected function isInIgnoreList(string $relationshipMethodName) } /** - * @throws ReflectionException * @return Collection + * @throws ReflectionException */ protected function getDefaultMethods(): Collection { @@ -481,9 +513,9 @@ function ($prefix) use ($functionName) { * created. * * @param string $functionName The name of the relationship method that was called by the user. - * @param array $arguments Any arguments passed to the relationship method. - * @throws ArgumentsNotSatisfiableException + * @param array $arguments Any arguments passed to the relationship method. * @return mixed Usually a Poser Factory, but could be a Model or Collection of Models. + * @throws ArgumentsNotSatisfiableException */ protected function buildRelationshipData(string $functionName, array $arguments) { @@ -523,8 +555,8 @@ protected function factoryShouldBeHandledManually(array $arguments) * For example, `withCustomers()` should return the fully qualified `CustomerFactory`. * * @param string $methodName The name of the method that was called by the user. - * @throws ArgumentsNotSatisfiableException * @return string The Poser factory class name that matches the function name. + * @throws ArgumentsNotSatisfiableException */ protected function getFactoryNameFromMethodNameOrFail(string $methodName) { @@ -555,7 +587,7 @@ class_basename($this), $methodName, * Constructs and returns fully qualified Poser factory name. * * @param string $relationshipMethodName The relationship method found on the Laravel Model. - * @param string $suffix A suffix that should be applied to the Poser Factory name. + * @param string $suffix A suffix that should be applied to the Poser Factory name. * @return string The constructed fully qualified Poser factory name. */ protected function getFactoryName(string $relationshipMethodName, string $suffix = "")