In my application, seed data is an unfortunate necessity. I don’t like it but it’s there, and it’s tightly integrated into many parts of the app (dropdowns, navigational links, and so on). Finding that seed data also tends to be rather ugly and long, unfortunately. Who wants to type
Tag.find_by_name('Health & Wellness') or one of the finder variations every time you’re looking for something? Not me, that’s for sure. I found myself aliasing these finders constantly as class methods: so, the above would be much more easily referenced as
Once I started duplicating this functionality across models I knew I had a concern. This is the module I came up with to encapsulate it.
The first problem with a concern like this is that it’s no easier to call class methods that have weird characters in them. You can do
Tag.send('Health & Wellness') but the goal here is to eliminate intervening calls, so that we end up with
send in there looks weird and doesn’t seem very clean.
I opted to fix this with a new String method I called
methodize. Put it in your lib folder and Rails will load it when the application starts.
1 2 3 4 5
Setting a Scope
The models that employ this concern will probably have different columns you’ll want to find them by. One might be called ‘name’, whereas another might be ‘title’ or ‘slug’. To get around these differences, our concern will assume that each model will have a scope that smooths over these differences. I called that scope ‘named’.
1 2 3
Creating the Concern
The concern itself is quite simple. It consists of one method,
class_methodable. We call that with an array of names that we want to turn into class methods. For each of those, we define a singleton method that sets or gets a class variable of the value we’re looking for. The code itself follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
Now that everything’s in place, actually using the concern is quite simple. In our class:
1 2 3 4 5
And in our code:
1 2 3
Now we can reference our seed data quickly and cleanly, without having to resort constantly to finders.