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:
…but that's time consuming. Especially if you have more than a few. Sometimes you want to stress test a larger data set (to show pagination, for example, or to work out JavaScript performance on larger data sets) or just give a better match to real data.
To accomplish this, I use the Storable and Faker gems.
Enter Storable
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.
Enter Faker
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.
Voila
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.