Making The Gem: Cold Shoulder
I've wanted to make a gem for a while, open source gems have really helped me along the way, and I've wanted to give back. I also know that I should package up my own code so I can re-use it in other projects.
The opportunity arose recently; I couldn't find a gem which provided the functionality I was looking for. Rather than just baking the feature into my app as a validator, I chose to make a gem!
Here is a recount of the gem, the process, and some gotchas that I discovered.
Speakeasy is a marketplace which helps people who need venues connect with interesting venues. Like other marketplaces, we knew we needed to keep users on our site—If transactions happen outside of our marketplace we lose revenue. So we decided to make cold_shoulder.
AirBnB has filtered email addresses and phone numbers from their user's messages for some time, we wanted to implement similar functionality.
This is how you impliment the gem. There are a few options, to ignore phones, emails, or twitter handles. As well as specify an error message in the event that any one of them are detected. Simple.
Two resources helped me a lot, the first was the guide "Make your own gem", the second was another validation gem date_validator that I referenced for things like localization.
Getting an empty gem set up and pushed to Rubygems.org was super simple. For some reason, minutes after deploying a gem, it will receive 15+ downloads. I think this is from automated testing services, but it might be real people!
How Cold Shoulder Works
Cold Shoulder has a few fuzzy regexes which search for very broad definitions of email addresses, phone numbers, and Twitter handles.
In the future I want to use Levenshtein distance to search for "numbers as words", i.e. "seven sseven two, ninee tree 4, sven six one ate" and have it detect the possible integers and decide if the words are close enough to one another to constitute a phone number.
Testing is a good practice, and while I can't say I write tests for all my code, I made sure to include them in this gem knowing it would be open source. I chose RSpec because I like it. You can see cold_shoulder's RSpect tests here.
The main thing which caught me off guard was needing to list all the files in the gem in the gem's Gemspec. I initially skimmed the more files section of the guide too hastily.
You have to include all needed files in the gemspec
My first attempt worked for me locally, but after pushing to RubyGems it wouldn't work. This is because when you run
gem build gemname.spec the necessary files were not being included. This did the trick (assuming you use git :)
I had some trouble figuring out how to get localized message to properly show in form validation errors. Fortunately @th1agofm had recently fixed Carrierwave so that it works with Rails 4. I used his commit as a reference for cold_shoulder.
Cold Shoulder is doing it's job on Speakeasy, but I will be adding more features to the gem soon. Hopefully this post helps other devs discover the gem. I'm looking forward to cold_shoulder's first pull request!