factory-stories
factory-stories copied to clipboard
Add 'with' to allow chaining of methods
This will allow use such as:
(new UserStory)->with(['isAdmin'])->create([ 'Full Name' => 'Ben Russell' ]);
Where your story looks like:
class UserStory extends FactoryStory
{
public function build($params = [])
{
return factory(User::class)->create($params);
}
public function isAdmin(User $user)
{
$user->isAdmin = true;
$user->save();
return $user;
}
}
This should let you create story "states" kinda similar to factory "states".
Let me know if you like the idea and have any suggestions or feel free to take it and implement a different way. Just currently I seem to have to make a new story for each different state, and would really like this kind of functionality in my project.
The idea is cool, but i think the problem described in your example could be solved just by using model factory states.
I the other hand, you can pass in the "params" array something like ['is_admin' => true ]
and then handle that situation in the build()
of the story class.
Do you have any other user case?
Yeah, to keep my example short, you are right that they could be done in model factory states.
One main use for factory stories I am doing is for different states of a shopping cart. I use the factory story to attach different relationships to the cart that I couldn't in a model factory, as well as other logic that's needed to create a working cart. So currently I have different factory stories for cart states such as a cart that is ready to start going through the checkout of choosing shipping options and one that has already gone through this process. Instead of having to nest a factory story, I was hoping to just be able to use one factory story, with states.
I hope that makes sense. Let me know if you have another question.
Even though states can be handled via a model factory, I think FactoryStory
should too for the convenience that build()
brings. However I think the method should be called states()
instead of with()
to mimic the model factory method .
So to reuse Ben's example, I suggest:
(new UserStory)->states('admin')->create([ 'Full Name' => 'Ben Russell' ]);
where the story is:
class UserStory extends FactoryStory
{
public function build($params = [])
{
return $this->factory(User::class)->create($params);
}
}
and we add something like this to FactoryStory
(untested) to delegate the states handling to the model factory:
class FactoryStory
{
protected $states = [];
// ...
public function states($states)
{
$this->states = is_array($states) ? $states : func_get_args();
return $this;
}
public function factory()
{
return factory(func_get_args())->states($this->states);
}
//...
}
then you just define the actual "admin" state in the model factory allowing it to be used by both the model factory and FactoryStory
the other advantage is that FactoryStory::factory() gives us a hook to modify the call to the model factory on the fly, maybe we could use that to handle times()
as well