DailyDogo 1022 🐶
DailyDogo 1021 🐶
A Limitation Of Laravel's Seeders - And Why It is There
Laravel has pretty cool tools to work with databases and fill them with seeded data. This is useful in many contexts, but mostly if you want to test things.
Seeders are cool, because they can make use of model factories - or factories for short - to create some test data the conforms to what we consider valid data.
However, the combination of seeders and model factories has a limitation and that is, that seeders are not meant to know of each others' results. So if you have three tables - users, blogs, posts for example - that have some kind of relationship to each other and would like to have individual seeders for those tables, then you can’t use factories in those seeders without some extra work currently.
Note that factories do not have this limitation. You can use recycle
on a model factory and use the resulting model in a subsequent factory call. This even works with indirect relationships, like a post that belongs to a blog and a blog also belonging to a user (and therefore the post belonging to a user). This short youtube video explains what I’m talking about:
So that’s pretty cool and all but if you want dedicated seeders for different parts of your database you’re still out of luck. Why would you want different seeders? Because you may want to separate the generation of seed data by entity. Sure, you could create a user which in turn also creates a blog with a handful of posts in it, but maybe you’d rather create a user, a blog and some posts and bind them to each other afterwards.
Separating the seeding procedure in this way will help you later, too, you might think, because if I ask you where posts are seeded, the answer could be “in the PostSeeder, duh”, if we could use that convention.
We would need to make it possible to receive the results of a seeder, but there is a problem: A seeder is supposed to create more than one row - or at least it should be possible work that way. So in other words: If we want to create a handful of posts per blog and we create one or two of those per user and we also create three test users (let’s say), how are we supposed to relate all of these disparate entities to each other even if we could take the results from one seeder with us to the next? How do we disambiguate the instances of the created entities? Which one of our 2 blogs should be connected to the 10 posts? Should it be five and five? Two and eight? How do we communicate that?
We would need to explicitly set specific entities created by the factory in the other seeder on the factory in the current, but it will become confusing rather quickly, because factories might also have states - like a user who is deactivated and so forth. And as I said, if we create more than one, how do we pick an entity?
Since it’s not easily possible to tell the next seeder what the previous seeder has created, having lots of seeders - e.g. one for each table - doesn’t make sense. We have to take the route, where we handle creating related but different entities in the same seeder.
Another practical problem comes from the fact that a database seeder doesn’t return its creates models, only the seeder classes it itself called. In order to still go the route of keep entities in their own seeders, we would need to enhance the basic database seeder classes Laravel provides. So from that perspective it seems that the framework itself doesn’t intend you to separate the creation of different entities using factories out into different seeders.
P.S.: It is kind of weird then, that when you create a model that you are also given the option to create a database seeder:
This seems to suggest that maybe there is an intent to create seeders for every model (or entity), but as I tried to show, this is not practical and the seeder classes themselves do not really follow that logic and do not afford you the functionality to communicate between different seeders out of the box.
P.P.S.: What you can do is communicate through the database, I guess. Meaning that if you create entities in one seeder - using a factory (or not) - you can of course read those rows from the database and relate different entities to each other by retrieving them from the database. But you’ll lose the elegance of expressing these relationships through the ORM and the recycle method.
DailyDogo 1020 🐶
DailyDogo 1019 🐶
DailyDogo 1018 🐶
DailyDogo 1017 🐶
DailyDogo 1016 🐶
DailyDogo 1015 🐶
DailyDogo 1014 🐶
DailyDogo 1013 🐶
DailyDogo 1012 🐶
DailyDogo 1011 🐶
DailyDogo 1010 🐶
DailyDogo 1009 🐶
DailyDogo 1008 🐶
DailyDogo 1007 🐶
DailyDogo 1006 🐶
DailyDogo 1005 🐶
DailyDogo 1004 🐶
DailyDogo 1003 🐶
DailyDogo 1002 🐶
DailyDogo 1001 🐶
That 1000th pic in my “Daily Dogo” series marks by sheer coincidence also the third year that Napu is on this planet.
She has not been with us from day zero, of course, that day will come in October. Also, I according to wolfram alpha, I have dropped 23 days somewhere along the way:
I guess I don’t mind it that much and I’m not going to fix it either. Especially in the beginning when doing things manually every day or when traveling and having to repair the streak things got at times untidy. But whatever.
Not all pics are great, but I am immensely proud to have stuck to publishing these for all this time.
A big thank you to anybody who liked these posts on Mastodon or MB!
And even bigger thank you to my partner E. who provided a good amount of the best pictures when I didn’t have any good photos (or sometimes any at all) of our shared little chaos agent.
If you’re curious how the process works: I use shortcuts and an app called Humboldt by Maurice Parker (@vincode on MB) to publish these posts semi-automatically.
Here are some screenshots:
This one is built out of two other shortcuts:
This one converts and then uploads an image of my photos app to MB.
This one looks at the rss feed of the daily dogo category and does some string manipulation to get the next number for the daily dogo.
So there you have it. Not very fancy. Not doing alt texts for these pains me at times, but I am pretty sure that I probably would have stopped the project when I had a tough time otherwise. It really is thanks to the shortcut that I managed to keep this up for so long.
DailyDogo 1000 🐶