ex_machina
ex_machina copied to clipboard
Allow sequences indices to be persisted between runs
I've found the Factory
methods provided by Ex Machina to be very useful in development. Often, when I'm manually testing code in IEx
it's handy to be able to quickly insert a record into the database.
One issue I've run into with this is that sequence IDs are not persisted between sessions. If my record uses a sequence and has a uniqueness constraint, I'll get errors until I've called it enough times to cause the constraint to go away.
If possible, it would be great if there were a way to configure Ex Machina to persist sequence IDs between calls. For example, if I fired up iex -S mix
and ran the following:
Factory.insert(:user) # %User{ username: "user1" }
Factory.insert(:user) # %User{ username: "user2" }
And then I closed IEx and restarted it, it would be awesome if it had this behavior:
Factory.insert(:user) # %User{ username: "user3" }
Factory.insert(:user) # %User{ username: "user4" }
Thanks for opening the issue @LandonSchropp! Currently, sequences use Agents to hold the state for the sequence. Your suggestion means we'd have to switch to saving the state in some other way. I'm not sure how we would be accomplish that. But if you have ideas, I'd be happy to review a pull-request.
In the meantime, I know it's probably not ideal, but you could modify the factory when you do manual testing to pass the start_at
option to the sequence. You can see that in the sequence docs:
def user_factory do
%{
# Will generate "[email protected]" then "[email protected]", etc.
email: sequence(:email, &"me-#{&1}@foo.com", start_at: 100),
}
end
Do you think that would help?
Thanks for the reply @germsvel! Your suggestion is definitely helpful in quickly solving my problem. 🙂
What I've done in the past with Fabricator
in Ruby was to patch the sequence generator and store the index to a temp file on every index generation. When the Fabricator first loaded, I would read the last sequence index from the disk and start it there.
I totally understand if this isn't something you're interested in adding to your package. I realize this isn't standard usage for factories—although it's useful!—so I'm content in closing this if you feel like it's out of scope.
If it's functionality you're interested in, I'm happy to create a draft PR around it.
Thanks!