Archive for the ‘Ruby 5’ Category

Ruby – Time.next(:friday)

Thursday, March 31st, 2011

This patch adds a method to find the next requested weekday.

Single Table HABTM with Rails 3

Friday, November 26th, 2010

I'm building a user model that keeps track of your parents and any children you should have. The acts_as_tree plugin
wouldn't have worked because it wouldn't allow for a parent to have many children. What's needed is a HABTM relationship. It's a quite simple relationship except for the :association_foreign_key option not being listed in the docs. Anyways I found some people discussing it here.


class User < ActiveRecord::Base
  has_and_belongs_to_many :parents,  :class_name => "User", :join_table => "parents_children", :foreign_key => "child_id", :association_foreign_key => "parent_id" 
  has_and_belongs_to_many :children, :class_name => "User", :join_table => "parents_children", :foreign_key => "parent_id" , :association_foreign_key => "child_id"
end

describe User do
  it "should have 0 children" do
    User.new.should have(0).children
  end
  it "should have 0 parents" do
    User.new.should have(0).parents
  end
  it "should have 1 child" do
    parent = User.new
    parent.children << User.new
    parent.should have(1).children
  end
  it "should have 0 parents" do
    child = User.new
    child.parents << User.new
    child.should have(1).parents
  end
end

Ruby5 #3 – Rspec stubbing named_scope in a controller

Friday, May 28th, 2010

I found the stub_chain method very helpful when stubbing out objects for Rspec controller testing.

My index action is calling 2 named_scopes and then doing a find.

 
  def index
    @exercise_logs = ExerciseLog.this_user(current_user).past.all
  end
 

When testing controllers your just trying to stub out a value for @exercise_logs not simulating an actual call to your model. So we'll use the stub_chain method to stub out our named_scopes like this.

 
    it "assigns all exercise_logs as @exercise_logs" do
      ExerciseLog.stub_chain(:this_user,:past).and_return([mock(ExerciseLog),mock(ExerciseLog)])
      get :index
      response.should be_success
    end
 

Resources:
http://stackoverflow.com/questions/1638814/stubbing-named-scope-in-an-rspec-controller/2930723#2930723

http://apidock.com/rspec/Spec/Mocks/Methods/stub_chain

Ruby5 #2 – Rails Securing Passwords

Friday, May 28th, 2010

It's important to filter out any sensitive data such as passwords from your log files. You can easily filter out data across your while application by calling filter_paramter_logging from your ApplicationController. In the example below I'm passing :password and :password_confirmation to remove their values from being placed in the logs.

ActionController::Base

 
class ApplicationController < ActionController::Base
  filter_parameter_logging :password, :password_confirmation
end
 

You will now see "FILTERED" in place of sensitive data.

 
  Parameters: {"x"=>"37", "y"=>"14", "action"=>"login", "authenticity_token"=>"JRFNcG9chNIpcsHoJzcQRRy1D6lIenjl7cWmvp3UpaI=", "controller"=>"videos", "user_id"=>"7-Jonathan-SpoonerJune", "video"=>{"password"=>"[FILTERED]", "email"=>"june@gmail.com"}}
 

Ruby5 #1 – How does a Ruby block work?

Friday, May 21st, 2010

Ruby implements Blocks, Procs and lambdas which are referred to as closures in the computer science community.

If you beginning to learn Ruby you will quickly run into code that looks like this.

 
a = ["dog", "cat", "bird"]
a.alter_each! do |n, i|
  "#{i}_#{n}"
end
 

So whats going on here?
We start off with an array of animal names and call the alter_each! method passing a block. In this block of code we can specify how we want to alter each item. Our example will prefix each animal name with it's position in the array. As the alter_each! method iterates through each item it will execute our block passing the value and index. Our block captures these params, prefixes the index to the name and returns the result.

Now lets look at the alter_each! method.
Notice the method doesn't specify any params, that's because a block is automatically assigned to yield keyword. yield is called like a function passing in the value and index of each item in the array and overriding the original value.

 
class Array
  def alter_each!
    self.each_with_index do |n, i|
      self[i] = yield(n,i)
    end
  end
end
 

What if you need to pass a param to this method?
You can modify the method signature to accept params and finally catch the block with a param starting with an ampersand. In the example below our block will be captured with the &block param which we will invoke the call method. This is in place of using yield

 
class Array
  def modify_each!(add_one = true, &block)
    self.each_with_index do |n, i|
      j = (add_one) ? (i + 1) : i
      self[i] = block.call(n,j)
    end
  end
end
 

Here is a full example that will prefix the index with the yield method and append the index with the call method.

 
class Array
  def alter_each!
    self.each_with_index do |n, i|
      self[i] = yield(n,i)
    end
  end
  def modify_each!(add_one = true, &block)
    self.each_with_index do |n, i|
      j = (add_one) ? (i + 1) : i
      self[i] = block.call(n,j)
    end
  end
end
 
a = ["dog", "cat", "cow"]
 
a.alter_each! do |n, i|
  "#{i}_#{n}"
end
 
a.modify_each! false do |n,i|
  "#{n}_#{i}"
end
 
puts a
 

For blocks in the wild check out the ActiveRecord save method.

 
def save(perform_validation = true, &block)
    return false if perform_validation && block_given? && authenticate_with_sorenson? && !authenticate_with_sorenson
    result = super
    yield(result) if block_given?
    result
end
 

References:
Understanding Ruby Blocks, Procs and lambdas