Skip to content
This repository has been archived by the owner on Dec 3, 2020. It is now read-only.

Commit

Permalink
Merge pull request #83 from lukeraymonddowning/craft
Browse files Browse the repository at this point in the history
Adds the `craft` and `craftOne` methods.
  • Loading branch information
lukeraymonddowning authored Jun 6, 2020
2 parents 3a5d678 + 2bfd34d commit 9e0888b
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 10 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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`.
Expand Down
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
52 changes: 42 additions & 10 deletions src/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
namespace Lukeraymonddowning\Poser;

use Closure;
use Illuminate\Support\Arr;
use ReflectionClass;
use ReflectionMethod;
use Mockery\Exception;
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -426,8 +458,8 @@ protected function isInIgnoreList(string $relationshipMethodName)
}

/**
* @throws ReflectionException
* @return Collection
* @throws ReflectionException
*/
protected function getDefaultMethods(): Collection
{
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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 = "")
Expand Down

0 comments on commit 9e0888b

Please sign in to comment.