Close and Go BackBack to Viget

Introducing ActsAsMarkup: A Markdown, Textile, Wikitext, and RDoc Plugin for ActiveRecord

Brian Landau
Brian Landau, Web Developer, August 12, 2008 0

On a project I’ve been working on recently, I wanted to be able to enter in Markdown text to a field and convert it into HTML in a view. Having read about BlueCloth’s performance problems though, I didn’t want to use the built in markdown helper in ActionView.

So I decided to give RDiscount a try, but I wanted to have the value for the column stored as a RDiscount Markdown object in the model object. So I started by creating an acts_as_markdown class method that took a list of columns to be represented as markdown objects. Quickly, my fellow Vigeteers and I realized it would be useful for a bunch of other markup languages as well, along with other Markdown libraries.

Continue reading "Introducing ActsAsMarkup: A Markdown, Textile, Wikitext, and RDoc Plugin for ActiveRecord"

Named Scope Caching

Brian Landau
Brian Landau, Web Developer, August 07, 2008 3

When working on high-traffic Rails sites, it often becomes necessary to find ways to improve performance with caching. One place we’ve found this is most convenient and easy-to-do is by caching an ActiveRecord result set for models that change rarely or not at all. An easy example of this is a Category model.

Often times, you have a categorization hierarchy that will never or rarely change over the life of an application. Ideally you would fetch the results once from the database and never have to again. So how do we go about caching this? First let’s look at our model and create a named_scope for it:

class Category < ActiveRecord::Base
  acts_as_tree
  named_scope :find_top_level, :conditions => 'categories.parent_id IS NULL',
                              :order      => 'categories.name'
end

Next, we need to create create a method that fetches the results for our new scope and caches it in a class variable. It should also only do caching if in production environment (alternatively or additionally, we could use the ActionController.perform_caching config value), as this can cause problems in tests.

def self.top_level
  unless ('production' == RAILS_ENV) && ActionController.perform_caching
    @@top_level_cache = self.find_top_level
  else
    @@top_level_cache ||= self.find_top_level
  end
end

Finally, we need to create a method to invalidate our cache when records are saved or deleted. Since we know this isn’t happening often (if at all), this should rarely be performed but is a good safeguard so we know our cache is current.

after_save :reset_cached_finder
after_destroy :reset_cached_finder

def reset_cached_finder
  @@top_level_cache = nil
end

This is something that we could easily see doing in a number of models for a number of finders. Since this involves a lot of similar code, it would be great if we could create some meta code that would allow us to define these caches with a simple one liner.

Continue reading "Named Scope Caching"

Second Ruby Hack Night: Aug 13th

Matt Swasey
Matt Swasey, Web Developer, August 04, 2008 5

The first ruby hack night was a success, so lets have another.  Good idea?  It’s going to be August 13th 7pm @ Murky Coffee in Arlington.  We’re going to trying and make these a monthly gathering, second Wednesday of every month.

Here is the upcoming entry, a small website will soon follow!

As before, bring your personal project ideas, or open source project experience, and be willing to share with the rest of us what you are planning on hacking, and what others could do if they wish to join your efforts.  It’s a casual environment, anyone is welcome, so please join us August 13th at 7pm.

I hope to see you there!

Introducing: EmailLabsClient

David Eisinger
David Eisinger, Web Developer, July 31, 2008 0

On my latest project, the client is using EmailLabs to manage their mailing lists. To simplify interaction with their system, we’ve created EmailLabsClient, a small Ruby client for the EmailLabs API. The core of the program is the send_request method:

def self.send_request(request_type, activity)
  xml = Builder::XmlMarkup.new :target => (input = '')
  xml.instruct!
  xml.DATASET do
    xml.SITE_ID SITE_ID
    yield xml
  end
  Net::HTTP.post_form(URI.parse(ENDPOINT),
    :type => request_type, :activity => activity,
    :input => input)
end

Then you can make API requests like this:

def self.subscribe_user(mailing_list, email_address)
  send_request('record', 'add') do |body|
    body.MLID mailing_list
    body.DATA email_address, :type => 'email'
  end
end

If you find yourself needing to work with an EmailLabs mailing list, check it out. At the very least, you should get a decent idea of how to interact with their API. It’s up on GitHub, so if you add any functionality, send those patches our way.

Hoptoad: in Brief

Tony Pitale
Tony Pitale, Web Developer, July 30, 2008 4

I was notified on Monday (or thereabouts) that Hoptoad had launched. Hoptoad is a service which stands to act as an intermediary between your Rails application exceptions and your email inbox. Any notification of exceptions raised will be delivered to Hoptoad and any repeat exceptions will be combined and counted. An email notification is still sent, but more intelligently (instead of hundreds of emails flooding your inbox).

Having completed registration, I added a number of separate projects. Instructions for setting up a Rails application follows. WIth a simple plugin, and a new initializer, my Rails application was all set to go.  I was able to configure and run the Hoptoad rake test in less than a minute. I did have to update an older project to Rails 2.1 and I’m not sure which versions specifically are compatible. All other projects worked without so much as a hiccup. As would be expected, a handy feed is provided.

After receiving an exception, Hoptoad will list it on the project’s page with a handy count of duplicate exceptions:

image

Exceptions appear to be compiled by an interesting combination of exception type, controller/action, and the exception message raised. The summary page details the time for the latest of each of the exceptions. Exceptions that have been reviewed on the site are marked as “resolved” and can be hidden. I was able to cull this information using the included rake test task, modified to raise a variety of exceptions, from different actions. I ran the modified task many times over to see how the errors would be combined. Any further insight into this process would be interesting to hear, so please leave comments.

Clicking on the exception will bring up all the wonderful details including details about the environment and the backtrace:

image

For new exceptions an email notification is sent:

image

I can’t vouch for the other members of the team here at Viget Labs but, for me, Hoptoad seems like a great fit. I always felt that email, while relatively immediate, was far too difficult to wade through with a large volume (my inbox doesn’t scale). I can understand the reason for reporting every single exception though the process always seemed inelegant. Hoptoad has successfully solved this problem, given my domain. I’ll report again after using Hoptoad in production for longer than a week.

We're the Developers

at Viget Labs. We write about web development trends, tips, best practices, industry events, and our projects — all with an emphasis on Ruby on Rails.

Recent Comments

Tony,

I understand and agree that the back-end shouldn’t output code (html code), and only content. The templates (aka views) should do the trick, but instead of having lot’s of if/else conditionals inside the view, you may just output the following content.

No information available

The template would loop in an array and put all the <li>’s inside the <ul>.
I don’t see anything wrong, nor...