Using Storable and Faker to Create Mock Collections
As part of my work, I often create prototypes of Rails applications. My preferred tool for doing this is Serve. But as excellent as it is, it's a very thin application with no persistence layer. To be honest, I don't really want a persistence layer at this stage. But there are times when I want to be able to iterate over collections of objects the same way that I would in a Rails environment. Creating an index view of subscribers is a great example.
Now, I could just draft this all as html:
Serve provides a
views/view_helpers.rb file, which is where I will store my ruby code. Since Storable can read YAML files (and because I do often use fixture data in real Rails apps), I use YAML as my data store.
Let's set up the data store first, using a
Subscriber model. You can go about this one of two ways:
- build your models by hand (the same way you would create fixtures for RSpec), or
- randomly generate a set number of models.
You should choose your approach based on what your end goal is; since I'm just trying to quickly populate a lot of data, I'll go with some random generation.
The ERB loop uses the Faker gem to create a first and last name, which it then uses to create the object's key and describe the object's attributes. This setup will create 10 of these objects. I could even use this later to seed fixture data for tests; in that case, I'd define those objects manually.
Now that we have the data store in place, let's do something with it: create some ruby objects:
This creates a class that we can marshal our data in to, enabling us to create our collection. The
field definitions default to being Strings, but (as you can see with
:id) you can specify a type using Ruby's hash syntax.
Massage that fake data!
I've also added a
full_name method to the class, since I know that I'll want to display a Subscriber's full name in the "first_name last_name" pattern. You can define any number of methods that you want here.
Next is a
self.bootstrap method, which accepts a file path as a parameter. This reads in the specified YAML file, processing it through ERB (the
load command with the ERB wrapper can be replaced by
load_file if you're just using straight YAML), and then creates a new Subscriber instance for each object defined in the YAML file.
Finally, there's the
self.all method, which similarly to the Active Record finder method of the same name, without the database call. It will search the active Ruby object space and return all of the objects of the Subscriber class.
This implementation of #all is a bit crude, but it works.
With all of that taken care of now, we can finally get back to our view and do this:
…which is much easier to maintain, especially if that bit of HTML code is rapidly changing. Storing the data in the YAML file (especially inside of a loop), means that adding/removing/modifying the object's attributes is much easier to do as well, and with a lot less typing.