Skip to content

Commit

Permalink
Updated some things, added another post.
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Bleigh committed Feb 10, 2009
1 parent 172b297 commit 96a1cfc
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 5 deletions.
3 changes: 3 additions & 0 deletions _layouts/master.html
Expand Up @@ -27,6 +27,9 @@ <h2>is Michael Bleigh on the web.</h2>
{{ content }}
</div>
</div>
<div id='footer'>
Copyright &copy; 2009 Michael Bleigh. Some rights reserved.
</div>
<script type="text/javascript">
//<![CDATA[
(function() {
Expand Down
@@ -0,0 +1,49 @@
---
layout: post
date: January 28, 2009
title: "HasAvatar: Defining an Application Vocabulary"
---

One of my favorite techniques to DRY up a Rails application is to pull out common functionality into a simple "vocabularized method," by which I mean a simple descriptive method call that can be made from within your model or controller definition. For instance, in some applications I might have multiple models that have an "avatar."

These avatars all behave the same and should do the same things so I don't want to just repeat myself in the code. Instead I set up a file called <code>has_avatar.rb</code> inside my <code>config/initializers</code> folder. We use "Paperclip":http://thoughtbot.com/projects/paperclip for attachment handling at the moment, so I am going to create a wrapper for the specific Paperclip functionality I need for the avatars. Here's the code:

<pre name="code" class="ruby">module HasAvatar
STYLES = { :large => ["200x200#", :png],
:medium => ["100x100#", :png],
:small => ["70x70#", :png],
:little => ["50x50#", :png],
:tiny => ["24x24#", :png] }

def self.included(base)
base.extend ClassMethods
end

module ClassMethods
def has_avatar
has_attached_file :avatar,
PAPERCLIP_DEFAULTS.merge(
:styles => HasAvatar::STYLES,
:default_style => :medium,
:default_url => "https://assets.presentlyapp.com/images/avatars/missing_:style.png",
:path => ":account/avatars/:class/:login/:style.:extension"
)
end
end
end

ActiveRecord::Base.send :include, HasAvatar</pre>

We define a module, <code>HasAvatar</code> that will add a new class method called <code>has_avatar</code> into whatever class it is included. I defined a constant <code>STYLES</code> that lets me access the style hash outside of the attachment definition. A final piece of DRYness in the code is the <code>PAPERCLIP_DEFAULTS</code> constant which is just the default setup for all attachments (S3 Bucket, etc.) and I override the options I need for the avatars by <code>merge</code>-ing them in.

<pre name="code" class="ruby">class User < ActiveRecord::Base
has_avatar
end

class Group < ActiveRecord::Base
has_avatar
end</pre>

Now both users and groups will have all of the expected Paperclip functionality without having to repeat ourselves. This is a simple example but it shows the general practices behind building your *application vocabulary*, which is just my made-up term for the abstract reusable components that are specific only to this application. Of course, if it's useful outside of the application, you might want to just go ahead and pluginize it!

The usefulness of these abstracted methods also comes in through the inherently polymorphic nature of Ruby. Throughout my code I can write helpers, views and more to support avatars without caring whether the object in question is a <code>User</code> or a <code>Group</code>. Basically, the DRYer you start the DRYer you stay.
6 changes: 5 additions & 1 deletion about.textile
Expand Up @@ -9,4 +9,8 @@ Michael Bleigh is the author of this blog as well as a Rubyist, designer, and op

Michael has contributed a number of open-source projects to the Ruby community including the "SubdomainFu":http://github.com/mbleigh/subdomain-fu and "ActsAsTaggableOn":http://github.com/mbleigh/acts-as-taggable-on plugins for Rails. He was also chosen to speak at RailsConf Europe 2008 as well as the Great Lakes Ruby Bash in 2008.

His work at Intridea has included being the product manager and technical lead for "Present.ly":http://www.presentlyapp.com/, the business micro-communications platform launched in September of 2008.
His work at Intridea has included being the product manager and technical lead for "Present.ly":http://www.presentlyapp.com/, the business micro-communications platform launched in September of 2008.

h2. About This Site

This site is built using the "Jekyll":http://github.com/mojombo/jekyll library and hosted on "GitHub":http://github.com/. The source code used to create this library is "publicly available on GitHub":http://github.com/mbleigh/mbleigh.github.com as well.
6 changes: 3 additions & 3 deletions blog.html
@@ -1,19 +1,19 @@
---
layout: master
title: Blog
full_posts: 4
full_posts: 5
---

{% for post in site.posts %}
{% if forloop.index <= page.full_posts %}
{% if forloop.index < page.full_posts %}
<div class='post'>
<span class='date'>{{post.date}}</span>
<h1><a href='{{post.url}}'>{{post.title}}</a></h1>
<div class='body'>{{post.content}}</div>
<a href='{{post.url}}#disqus_thread'>View Comments</a>
</div>
{% else %}
{% if forloop.index == page.full_posts + 1 %}
{% if forloop.index == page.full_posts %}
<h3>Older Posts</h3>
<table class='post-list'>
{% endif %}
Expand Down
6 changes: 5 additions & 1 deletion open-source.html
Expand Up @@ -3,4 +3,8 @@
title: Open-Source Projects
---

<h2>Open-Source</h2>
<h2>Open-Source</h2>

<ul id='open-source-projects'>

</ul>

0 comments on commit 96a1cfc

Please sign in to comment.