Archive

Simple Sparklines in Merb

Basic reporting with Sparklines in Ruby web application frameworks is pretty simple. It is especially simple if you are using Ruby on Rails, and the available Sparklines plugin. For some, it may not be quite as clear if you wish to not use the plugin, or if you are using one of the other frameworks, such as Merb.

I have been trying to take a moment, when I can, to build something with Merb. It's been slow going. (Part of that problem is that, when I do have some time, I find myself quite easily distracted. I mean, I can't even be relied upon to churn out some rambling prose in this space once a week!)

I am having a lot of fun with it. I am building a little application to track my weight losses (or gains) over time. As you can guess, it is very basic, but that's all I personally need. I would like to be able to see a little line graph of how I'm doing, though. It is extremely convenient to have your self-esteem ruined by a mere glance at a web page. Other applications take some reading of actual numbers! In this way, I can be utterly discouraged, and contemplating death-by-overeating before I've even finished my triple grande carmel mocha (560 calories?).

How can I get started, already?

First of all, you should know that Mr. Topfunky does a fine job of explaining first the "Why" and then the "How" in using Sparklines for reporting in Better Reporting with Sparklines. Again, we're talking about much more experienced and knowledgeable writer and programmer here. Check it out. That said, I hope you'll bear with me. I mean, even junior high basketball teams have a B-team, right?

Oh, Smart Blahgging: Send Me to Someone Else's Site

Sorry, we'll just get straight to it. Install the gem:

sudo gem install sparklines

Seriously, generating sparklines is simple. It really is. The first thing you will want is a controller to handle the sparklines reports.

script/generate controller reports

We want to require sparklines in the controller.

require 'rubygems'
require 'sparklines'

class Reports < Application
end

Next is the meat of the this tip: generating the graph. Similar to Mr. Topfunky, I put the code in the show method of my Reports controller. Essentially, we want this method to return the image data.

require 'rubygems'
require 'sparklines'

class Reports < Application
 
  def show
    graph = Sparklines.plot_to_image(current_user.weights,
      {   
        :background_color => 'transparent',
        :step => 30,
        :height => 30,
        :line_color => "#ffcccc",
        :underneath_color => "#ebf3f6"
      })
    graph = graph.to_blob
  end
end

Simpler, please?

Notice, I didn't called 'render'. I just return 'graph = graph.to_blob'. I end up calling this controller method within an image tag. Yup, that's right! (This is in HAML, in case you hadn't noticed....)

%img{ :src => url(:report, 'a unique identifier') }

I know, I know. What's with the 'a unique identifier' crap? Well, technically, the Reports#show method should be showing some single unique entity, identified by the passed parameter (params[:id]). However, I wanted to keep things simple, for myself as much as for those reading this. As your application gets more complicated, you may want to add more reports. I am sure I will eventually, even if it's just 'weight change over past month', 'weight change over past 2 months', and 'weight change over past 3 months'. At that point I will identify what reports I wish to use by the passed id. Until then, this is working as a quick, dirty solution.

For now, I've got a very simple report. It looks like this:

Screenshot of Weight Report

That's the very basic way to pull off Sparkline reports in Merb. Again, you can have several unique graphs easily enough. You could also break the basic options for 'plot_to_image' into another method, as did Mr. Topfunky. Caching the results of these graphs is probably not a bad idea either. These things are all up to you, for now. Enjoy playing with your graphs. May they be as depressing and tear-provoking for you as they have been for me.

Note: The weights in that screen shot do not represent real data. I haven't weighed so little since I was dirt poor and living off celery and peanut butter for meals once or twice a day. (No really, that happened. Hungry constantly, but that's the best I've every looked. HA!) Also, I know what Mr. Topfunky's name is. It's a lot more entertaining to me to refer to him as Mr. Topfunky. It's no Mr. Splashy Pants, but it's close.

Disabling Timestamps by Model in Rails 1.2.x

I recently had a need to disable the timestamp for 'updated_at' for one particular little update to a table. At work, we are stuck on Rails 1.2.x for the time being. ActiveRecord::Base does indeed have a class accessor called 'record_timestamps' that can be set to true or false. However, in Rails 1.2.x, this is not class inheritable. So, I set about fixing that.

Note: If you are using Rails 2.0.x, you can safely ignore this. You may want to read through Evan Weaver's 'hacking activerecord's automatic timestamps', though.

Crap. Can't you just do this for me?

This is easy, I swear. Like I said, it's really already been done, so you don't have to do any revolutionary hacking of any sort. In fact, you just need to change a few characters on one line of one file in ActiveRecord's Timestamp class, just like they did in the actual patch to Railsa.

Where is this timestamp crap?

In your Rails app's root directory, open up 'vendor/rails/activerecord/lib/active_record/timestamp.rb' file. (You did already freeze your Rails application, right?) Find the following line:

base.cattr_accessor :record_timestamps, :instance_writer => false

The part we are interested in changing is 'cattr_accessor'. We want to make it class inheritable, and 'cattr_accessor' does not allow such behavior, as Dr. Nic pointed out, once upon a time. Luckily, ActiveSupport provides 'class_inheritable_accessor'. So, change the above line to the following:

base.class_inheritable_accessor :record_timestamps, :instance_writer => false

Uh, what now?

Good. Now, I created a class method in a model that should be used as a block to turn off timestamps for any table updates within.

class SuperBowlLosers < ActiveRecord::Base

  def skip_stampings
    self.record_timestamps = false
    yield
    self.record_timestamps = true
  end

end

Now, elsewhere, I can make a minor update to a field without updating the 'updated_at' portion.

  # Should probably be done every few minutes
  @pats = SuperBowlLosers.find_by_year(2008)
  SuperBowlLosers.skip_stampings do
    @pats.update_attribute(:pissing_and_moaning_and_crying_at, Time.now)
  end

TA DA!

See? That wasn't so bad, was it? For methods other than my 'skip_stampings' method (that I did not dream up myself, as you'll see), check out Evan Weaver's 'hacking activerecord's automatic timestamps'.

Storing Passwords the Un-Giles-Like Way

Giles Bowkett wrote an entry in his blog today, introducing his Ruby gem 'password'. (The article is sudo gem install password.) As you may have guessed, the gem allows you to store user names and passwords that you might otherwise forget. Unfortunately, all it does is take them and throw them in a text file, in plain text. Mr. Bowkett goes on to explain his philosophy about passwords and web applications. It can best be summarized by the sentence, "I don't give a fuck." (No, really. Go read it, it's a decent read. These are his words.)

Why is this a big deal?

I am not going to preach about the dangers of saving passwords in plain text. It's obvious to everyone, and it is more than obvious to Mr. Bowkett. He makes his position clear. In fact, the focus of his article was not even his 'password' gem, really. His focus was registration requirements for websites and why they suck.

The reason I am referencing the article is because of that gem, though. I'm sure it's a perfectly wonderful gem, with some perfectly wonderful code. Unfortunately, it's completely unnecessary. There is a perfectly good command-line utility called 'pwsafe' that stores your encrypted passwords in a database for you. I'll mention it again: encrypted.

If you're on Ubuntu or a derivative:

sudo apt-get install pwsafe

It's pretty straightforward. You can have groups of user name-passowrd combinations. You can set a password (separate from your OS user account) for the database. You can set it up so that it requires you to use 'sudo' to run the program. Eventually, you can just ssh into your box from anywhere, enter your credentials, and get that damned Remember The Milk password that you keep forgetting. (Forgetting that particular user name and password makes keeping track of your task list a bit difficult, by the way. I don't remember how to work this 'pen and paper' ridiculousness.)

Cool! How secure is that?

I am sure a security expert could come here and school me on the actual security of using pwsafe. I am not an expert. However, it's certainly better than plain text in a plain file. Far better.

Do you actually use it?

I have been using the program for quite a while, and I love it. I like using 'pwgen' to generate random passwordsfor different things that I have to register (Yes, Giles, it does suck). I can't remember all of them. Hell, I can't freakin' remember what I had for lunch yesterday. Throw them in here with a reasonable reference name (uh, such as, 'rememberthemilk.com'), and you're good to go.

Powered by Drupal - Original Theme by Artinet - Theme Enhancements by Me