ex_machina icon indicating copy to clipboard operation
ex_machina copied to clipboard

Allow sequences indices to be persisted between runs

Open LandonSchropp opened this issue 2 years ago • 2 comments

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" }

LandonSchropp avatar Jul 16 '21 20:07 LandonSchropp

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?

germsvel avatar Jul 22 '21 10:07 germsvel

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!

LandonSchropp avatar Jul 23 '21 17:07 LandonSchropp