Writing My First RubyGem - CanBe

I started working on a personal project in Ruby on Rails, that probably will not see the light of day. I had an Active Record model that could have different attributes depending on the type of record that it was. In Rails, there are different ways to create your models to handle data in this manner. For example, you could have a different model for each type of record. However, this creates some challenges when querying the data. It would be difficult to query data to return a result set that would include different types of models.

You could also use ActiveRecord Single table inheritence to implement the functionality that met my requirements. That’s when my data modeling and DBA experience kicked in. Using STI would result in database rows with many null values in them. This didn’t feel right to me.

That’s why I wrote the CanBe gem. With the CanBe gem, you can declaratively define the possible types for any given instance of your model. Initially, it just provided many helper methods to ensure consistency. Then I enhanced it to allow for different attributes depending on type of model instance that you are accessing. To accomplish this, I used polymorphic associations to connect up different models that represent the specific attributes required for the instance type.

As of version 0.2.1 of the CanBe gem, I have implemented most of the functionality that I wanted to include. There are still a few more tweaks that I would like to make. I am hoping that other developers will find the functionality useful. If you want to see functionality, that is not currently included, feel free to contact me or submit a pull request. Contributions are always welcome and appreciated.

Writing my first gem has been a great experience! It furthered my knowledge of the Ruby language and how to integrate with Ruby on Rails, specifically ActiveRecord. I was able to apply TDD techniques to ensure the gem didn’t break as I added new functionality. I worked with Travis to ensure that my code was integrated properly when changes were made.

I hope that others find the CanBe gem useful for their projects!

Comments

I’m Going to Write a Book!

Well that sounds like a really ambitious title, doesn’t it?

It is, but it’s something I’ve wanted to do for a long time. However, I have one really big problem - I’m not confident in my writing ability. I’ve always avoided writing and it’s always been challenging for me. This goes back to grade school for me. That’s all about to change!

I’m going to start writing on this site more.I’m a life long learner and I tend to focus a lot on learning new technologies, specifically software development techniques and programming languages. For the most part, I will write about technology related information, sharing helpful tips as well as my many opinions on software development and how things should be done.

Why do I think that writing more will help be to become more confident in my writing? I have written software in many languages. C#, Ruby, HTML, JavaScript and SQL just to name a few. I have only gotten better at them by writing more software. Some of the software I have re-written to learn a new language or to apply new techniques that I have learned. It’s my opinion that the same can happen with the English language. Only time will tell if my assessment of how to become more confident in my writing abilities is accurate.

Becoming a better writer will help me both personally and professionally. Personally, becoming a better writer will enable me to write much longer works, like a book, and allow me to meet some long-term personal goals. I have no clue what I want the book to be about. I’m sure that will eventually work itself out.

On a professional note, I spend a portion of my time documenting the systems for which I am responsible and being a better writer will help to produce better documentation. By better documentation, I mean it will communicate the information in a more effective and efficient manner. Also, for work, I am constantly on HipChat and Skype and it is important to be concise and to the point as to not waste the readers time.

I hope you enjoy what I write and I look forward to your feedback!

Comments

Getting Backbone.js to Sync With Rails and Mongoid

I have started working with Rails, Backbone.js and mongoDB. I chose Mongoid as the ODM to handle all of my ActiveModel needs within my Rails app. The biggest challenge I ran into, with this configuration, was trying to get all of the syncing functionality working between Backbone.js and Rails.

Fortunately, the URL scheme that Backbone.js uses for syncing data matches perfectly with Rails’ Resource Routing. However, this relies on the JSON that is sent to a Backbone.js model to have a property of id. But the JSON that is emitted form Rails/Mongoid/mongoDB does not have that property. It has an _id property to represent the id of the document.

I have found two ways to solve this problem. First, as this blog post suggests, you can modify the JSON that is emitted. I don’t care for this approach, because this then modifies the every request for JSON, unless you override what you have already overridden. I prefer the approach of letting Backbone know how to interpret your data.

This can be done by setting the idAttribute property within you model to "_id", see the example below.

Set the idAttribute on a Backbone model
1
2
3
var Sidebar = Backbone.Model.extend({
  idAttribute: '_id'
})

Once you have set this in your Backbone.js model, all of the syncing functionality works as expected. Also, when you need to access the id property of your Backbone.js model it works with the id property that is provided by backbone. This setting is not documented on the main Backbone.js page, but you can find it in the annotated source code here.

Comments

Keeping an Eye on Productivity

Recently, I started working on my first Ruby on Rails project at work. The project is also using Backbone.js. The Rails And Backbone communities are very active. I felt that I needed to keep up with everything that was going on in the communities. I tried to accomplish this by researching and possibly trying every new gem that came out so I could completely understand and choose the best options for this and future projects.

However, I wasn’t being very productive and moving the project forward. Instead I spent most of my time reading blog posts and writing prototype code. Also, all of research and prototyping wasn’t helping me become more proficient with Rails and Backbone.js.

So, I decided to change my tact and focus on the project at hand. I only went out perusing the interwebs to find what I needed when I needed. It’s been about a week now that I’ve been doing this and I have written many times more code than I did in the previous weeks. The project is now moving much faster and I am learning much more.

I must say that this process isn’t producing the prettiest or most efficient code, but I am fairly in-experienced with Rails and Backbone as compared to other languages that I know. And let’s be honest, very few people care about the quality of the code, only other developers that have to maintain the code and your future self. What the majority of people care about is, “does the product do what it’s supposed to do.”

I plan to keep up working in this manner to complete the project and to be more productive. I am becoming more proficient with Rails and Backbone.js. I also feel that I am in a better position to evaluate if and when to use a gem to accomplish a given task.

How do you balance “keeping up” vs. actual productivity?

Comments

Python Meta-programming Gotcha With __getattr__

Recently I’ve been working with Python at work. I’ve had to create a very lightweight ORM and each model class derived from the base model class. However, to access the fields in an instance of a model class required some meta-programming. This was pretty straight forward since Python provides the __getattr__ that gets executed when a field is not found. But I did run into one gotcha!

In my __getattr__ method, I was determining the value of the property that was being accessed from an internal dictionary that stored the values of the model fields. However, something really strange was happening. The __getattr__ method was being called for properties that were defined directly on the class. An example of this can be seen here.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Example(object):
    @property
    def foo(self):
        return 'bar'

    @property
    def boom(self):
        raise AttributeError

    def __getattr__(self, name):
        return 'Trying to get the {0} property.'.format(name)

v = Example()

print v.foo
>>> 'bar'

print v.boom
>>> 'Trying to get the boom property.'

It turns out that what was happening was that I was trying to access the boom property from the Example class and it was trying to be retrieved from the __getattr__ method implementation. This threw me for a loop because I am still fairly new to Python.

From the example above you can see that the foo property works correctly, but the boom property runs the __getattr__ method when accessed. If an exception is thrown in the @property method, the Python class will revert to using the __getattr__ method. Once I addressed the underlying exception everything worked properly.

Comments