skinny controllers in Rails

Thursday, 26 March 2009

Your controller is so fat I took a screenshot of it last Christmas and it is still printing. We have all heard stories about how we should keep our controllers slim and fit but there can never be a definitive answer on how to accomplish the athletic pose. For you see, there are an infinite amount of ways that your controller can take on husk. In this blog-post I will attempt to define and solve one of these problems.

Let us suppose that you have a User model and a Job model.

class User < ActiveRecord::Base
  has_many :jobs
end
 
class Job < ActiveRecord::Base
  belongs_to :user
end

Ok, so this proverbial Job is a very complex model. It has many attributes that are activated by complex algorithms. The job’s algorithms are influenced by input from the user.

class Job < ActiveRecord::Base
  belongs_to :user
 
  def algorithm!( input )
    case input
    when :variation_one
      # do a bunch of crap
    when :variation_two
      # do even more crap
    end# case
  end# algorithm
 
end# Job

Now that we have this model with extremely complicated algorithms that depends on loads of user input; we need to find a RESTful way to call these methods. Please keep in mind that these methods require the users input which will come from the params hash. Since our app is RESTful, we will be ‘updating’ the object by sending a PUT request with data that will be received by the Jobs controller.

Our edit.html.erb should have something like this in it:

 
<%= f.check_box :important_input_that_is_not_apart_of_the_model %>

This data’s purpose is to instruct the algorithm on how to execute. However, it is not apart of the model. There is NO column that corresponds to this data. So the question now becomes: How do i get this data from the view/controller (params hash) to the model?

The way I attack this problem is by adding this to my model:

 
class Job < ActiveRecord::Base
  belongs_to :user
  attr_accessor :important_input_that_is_not_apart_of_the_model
 
  def before_save
    self.algoritm!( self. important_input_that_is_not_apart_of_the_model )
  end
 
  def algorithm!( input )
 
    case input
    when :variation_one
      # do a bunch of crap
    when :variation_two
      # do even more crap
    end
  end# algorithm
end# Job

In this case we have added NO extra code to our update method in the Jobs controller. However we have added heaps of functionality.
Let me know if there is better way to do this ?


navigating file tabs in TextMate

Friday, 13 March 2009

I like uniform key commands. Hence the following quick tip.  Now i can move between tabs in TextMate with ease.

System Preferences -> Keyboard & Mouse -> Keyboard Shortcuts.

Now, add a new short cut and name it “Next File Tab” and then add whichever keyboard shortcut you prefer. Do likewise for “Previous File Tab.” Voila!


and we’re back.

Wednesday, 11 March 2009


Rake is cake!

Tuesday, 10 March 2009

I Have been using C++ the last few days and without an IDE to boot. I am so comfortable with TextMate that i started to vomit when i began working in xCode. This is discouraging as i have an Objective-C project looming over my future. However, for the time being i decided to keep my Mate.

I quickly got swamped with all sorts of dependency issues, hence i found Rake. Here is my file:

 
require 'rake/clean'
 
  APPLICATION = 'one_upper'
  CLEAN.include('*.o')
  CLOBBER.include('one_upper')
 
  task :default => ["#{ APPLICATION }"]
 
  SRC = FileList['*.cpp']
  OBJ = SRC.ext('o')
 
  rule '.o' => '.cpp' do |t|
    sh "g++ -c -o #{t.name} #{t.source}" 
  end
 
  file "#{ APPLICATION }" => OBJ do
    sh "g++ -o #{ APPLICATION } #{ OBJ }" 
  end
 
  # File dependencies 
  file 'main.o' => ['main.cpp', 'stack_manager.h']
  file 'stack_manager.o' => ['stack_manager.cpp']

I updated my TM Bundle to reply with a ” rake ” command whenever i hit apple-B.


Newton’s Method .to_ruby

Sunday, 8 March 2009

here is the math behind Newton’s Method

PRECISION = 0.0001
 
def newtonian_guess( guess,fx,fdx )
  loop do
    better_guess = guess - ( fx.call( guess ).to_f / fdx.call( guess ).to_f )
    return better_guess if ((better_guess - guess).abs <= PRECISION)
    guess = better_guess
  end
end
 
def sqrt( num )
  guess = num/2
  return newtonian_guess( guess,
            lambda {|x| (x**2)-num } ,
            lambda {|x| 2*x } )
end
 
class Float
  def to_sqrt
    sqrt( self )
  end
end
 
p 2.0.to_sqrt
# => 1.41421356237469

terminal tip #1

Tuesday, 3 March 2009
open . -a finder

will open the current directory with finder.


things.app vs omnifocus

Saturday, 28 February 2009

things_vs_omnifocus

requirements:

  • Simplicity
  • Group TODOs with projects
  • iphone app
  • syncs with basecamp
  • iCal integration

Things.app

I evaluated this solution first. I was initially drawn into this product by its wonderful use of OSX goodness. They have a very sleek interface that allowed me to quickly understand my data. The work flow is very nice. I start by brain-dumping my tasks to  the inbox and then filtering the inbox into two my granular compartments. Things makes sorting the inbox super simple. I add due dates to all of my TODOs and Things will show me these TODOs on the date of their deadline. They also have a nice container for “someday” projects. My someday box is growing exponentially.

Pros:

  1. Interface
  2. elegant HUD for adding new todos
  3. less money than omnifocus

Cons:

  1. No integration with BaseCamp ( for now )

OmniFocus

After 20 days of using Things, i decided to give OmniFocus a shot. The bar was already set really high. Unfortunaltly this may have slanted my opinion. Nevertheless i gave OmniFocus the college try.  OmniFocus is developed by the Omni Group, makers of OmniGraffle - one of my favorite tools. This is probably the reason why OmniFocus is a bust. It is to complex for what i wanted. It seems very powerful, as does the learning curve. Four days into using OmniFocus and one of Einstein’s famous quotes came to mind: “Everything should be made as simple as possible, but not simpler.”  It appears that OmniGroup had never considered this when designing OmniFocus.

Cons:

  1. Crap interface
  2. bloated

bottom line

Things.app !


words

Thursday, 12 February 2009

words


Code on Shakedown Street

Thursday, 5 February 2009

This has got to be the wildest thing that i have ever heard. There can be no way that Cisco approves of this. . . . Programming on LSD; really!?

cisco_on_acid


brain on television equals tapioca

Monday, 2 February 2009
Calvin and Hobes Television Tapioca

Calvin and Hobes Television Tapioca