Paperclip Resized Image Details In to_xml

Posted by kris on June 18, 2009

I love paperclip. In fact, I love paperclip enough to name my next child paperclip. The issue at hand is calling to_xml on an object that is using paperclip. What you end up with is something like this:

That doesn’t give us any real useful information about the attached image, such as the file path to the file or the styles. So, I figured, lets overload to_xml, but I did not want to have a huge nested builder setup in my model, after all, we are talking about Ruby, there has to be a fairly clean way to do it. So, I browsed around and found you can pass proc objects in the options you pass to to_xml. Here is how my to_xml turned out.

Basically, I just create a Proc to loop over the styles I use for paperclip, and build a tag for each one based on the style. Then, I ignore the original paperclip columns, as I don’t really need those. Finally, pass the options off to super() and call it a day. The result will look something like this:

Hope this helps others. Let me know if you have a cleaner method of doing this.

Monkey Patching RubyOnRails Caching For Debugging 2

Posted by kris on June 15, 2009

One of my current projects at work involves ajax rating for videos. The problem is the index page displays 24 videos. That’s 24 additional queries per page load, or an excessive amount of joins. To speed this up, I implemented fragment caching. The problem I ran into was that even when console stated that it expired the cache when I would rate a video, the cache file would never be removed, and thus, on page reload, would display the original rating. I thought I was going crazy so I dug into the Rails code, particularly ActiveSupport::Cache::FileStore and took a peek at delete. What I found was amazingly silly.

Look close at the rescue block. “If there’s no cache, then there’s nothing to complain about”. What if the cache exists, but there is another possible error? How would I know what the error was? Since I know the cache existed in tmp/cache/ I decided to monkey patch it.

What I found was fragment caching was reading and writing cache to one path, then trying to delete from another. It turns out I was not paying attention and expire_fragment treats a hash as parameters for url_for. Changing my key to a string solved it.

So what have we learned? Just because Rails rocks doesn’t mean some code isn’t ass backwards. Never be afraid to jump in and debug core for yourself.

RubyOnRails Route Generation Awesomeness

Posted by kris on May 12, 2009

Before I decided to leave work, I wanted to get this photo album system started. It’s polymorphic and allows users, videos, etc, to all have albums. I wanted to use a single controller, views, etc. Well, I never knew that you could do the following:

Assuming @parent is the parent object owning the album, it will generate a link to /admin/videos/5/albums

How awesome is that.

RubyOnRails Breadcrumb Helper

Posted by kris on May 12, 2009

I needed a stupid simple breadcrumb helper that was fast and didn’t require crazy configuration. I don’t need a high level of control, so I figured, lets just take the requested path and link the segments, and here we have it.

Feel free to leave feedback.

Github Issue Tracking 1

Posted by kris on April 18, 2009

I’ve been using Github for personal and work projects and have come to love it. The only real request I had was issue tracking. Today I opened my newsreader to find they just added this feature. I’m happy they added it, but was hoping for a few more features, such as:

1. Priorities. I don’t like having to reorder for priority.
2. Attachments. My company tends to have lots of design work. I suppose they can potentially commit to git then link to it? Still a bad way of doing it.
3. Assigning Issues. Why can’t Github give you another drop down to select who to assign the issue to based off contributors? Labels is extremely broad and can make it hard to find the “label” you want quickly.

Glad they added it, but I hope they can look into these features so I can drop Lighthouse and BaseCamp.

A Neat RubyOnRails Profile Link Helper 1

Posted by kris on March 17, 2009

I am working on a project for my client and they have a movie and an associated list of actors. When viewing a movie, they want to be able to list all the actors starring in it, obviously.

This uses map to iterate over each actor, link to their profile, pass any options we want, then assemble with to_sentence. To use it is extremely simple.

Simple, as it should be.

Using RailRoad to visualize your model relationships 3

Posted by kris on February 04, 2009

I’m down in L.A. doing some work with a company and was documenting the way their system works. I thought to myself, ‘It would be awesome if I could visualize the model relationships’, after all, they had an excessive amount. A quick google search returned RailRoad. Simple to install:

$ gem install railroad

Then it’s just a matter of running it.

$ cd rails_app/
$ railroad -aio models.dot -M

To view the models.dot you need to install, if on a Mac, graphviz. Unfortunately the pkg they have for download doesn’t work on Leopard, so you will need to install from macports.

$ sudo port install graphviz

Then, to convert to PNG, simply:

$ dot -Tpng models.dot > models.png

Here is a sample png image from the railroad website when run against the depot project.

Simple, eh?

Why my next child will be named Paperclip 3

Posted by kris on December 30, 2008

Ok, I lied, my next child will NOT be named Paperclip, but I thought about it for a moment. Aside from the simple fact that it makes attachment_fu its bitch, there is a simple feature that just makes my butt wet. You know, that one feature that makes you ignore your own child.

The ability to regenerate all thumbnails whenever I change a photos size attributes. Thank you paperclip, and god bless. Btw, Mason Browne swears he showed me paperclip, but we all know the truth.

RubyOnRails Seed_fu and Paperclip woes

Posted by kris on December 05, 2008

If you aren’t aware of Seed_fu, it’s a fantastic plugin for RubyOnRails that allows you to populate your database with data, not with yaml files, but with code. Paperclip is an attachment plugin, which, in my opinion, dominates over attachment_fu.

All was fine until I was building a seed for my default admin user. Every time I tried to seed, I’d get a wonderful `IO stream closed’ error. Upon investigating, it boiled down to the line:

File.open(File.join(Rails.root, 'public', 'images', 'avatar.jpg')) { |f| user.avatar = f }

I couldn’t figure out what was going on. After all, dropping to script/console and doing it by hand yielded success. So I switched it up and tried the following:

f = File.open(File.join(Rails.root, 'public', 'images', 'avatar.jpg'))
user.avatar = f

What do you know, it works! I asked a few people and they had no idea what was going on. Perhaps it had something to do with streams and blocks? If anyone has an idea, I’d love to hear it.

Nifty RubyOnRails Layout Method 2

Posted by kris on August 01, 2008

So I find myself in many situations where different actions need different layouts, which is common in large multiuser systems. For example, in my system, when you are viewing a user index, it loads the layout ‘application’. When you’re viewing the edit action, it loads the layout ‘profile’, otherwise it loads the layout ‘user’. I hacked up a tiny method to toss in the application controller:

# application controller
def find_layout(params, default = nil)
  default ||= controller_name
  params[action_name.to_sym] || default
end

# user controller
before_filter do |c|
  c.find_layout({
    :edit => 'profile',
    :index => 'application'
  })
end

As you can see, you simply pass a hash to the find_layout method with the actions and the layout to use. You can optionally do:

before_filter do |c|
  c.find_layout({
    :edit => 'profile',
    :index => 'application'
  }, 'some_other_default_layout')
end

This will make the default layout ’some_other_default_layout’. I know this could probably be improved in many ways, but it’s simple, it works, and that’s what I like.