Sunday, December 30, 2007

Simply Rich Authenticator using Rails 2.0.2

This is a mini Rails App that uses RESTful authentication and Acts as State Machine to implement: 1. Signup 2. Activation 3. Forgot Password 4. Reset Password 5. Change Password Download it here. Code is available under Rails MIT license. You can check out the code from: svn checkout *http*://simply-rich-authenticator.googlecode.com/svn/trunk/simply-rich-authenticator-read-only Happy New Year! P.S: I have fixed the file size problem. So enjoy the screencast.

Saturday, December 29, 2007

Friday, December 28, 2007

How to develop plugins in Rails - Part 4

In this episode we will revisit the include and extend and learn how it is used when
developing Rails plugins. Download it now : How to develop plugins in Rails - Part 4

Sunday, December 23, 2007

Alias in Ruby

Learn about alias method in Ruby

Upgrading RubyGems to 1.0.1

If the sudo gem update --system hangs then try:

sudo gem install rubygems-update
sudo update_rubygems

This successfully installed Rubygems 1.0.1 on my Powerbook G4. Old version was 0.9.1

Tuesday, December 18, 2007

Time Management for Software Engineers

Today I read the book 4 hour workweek by Timothy Ferriss. While I am not totally convinced by his business ideas, I definitely learned a lot about time management. Check it out in your local library or book store.

Monday, December 17, 2007

Upgrading to Rails 2.0.2

If you are getting the following error during upgrade of Rails:

ERROR: While executing gem ...(OpenURI::HTTPError)
404 Not Found

1. sudo gem update --system.
This will upgrade the Ruby gems to 0.9.5

2. sudo gem install rails --source http://gems.rubyonrails.org
Note that gem install -y is the default, so you don't have to provide it.

Class_Eval in Ruby

Here is the screencast download link for learning about class_eval in Ruby.

Sunday, December 16, 2007

How to install Rails 2.0.1 in Cent OS

gem install rails -y --source http://gems.rubyonrails.org --no-rdoc --no-ri

No documentation will be installed on the production, saves disk space. source option is used if you have difficulties installing.

Friday, December 14, 2007

Thursday, December 13, 2007

Data Migration using ActiveRecord

If you are using ActiveRecord to create new records while you are migrating from a old database, use new instead of create when you want to use the same primary key. Because create does not allow you change the primary key.

Friday, December 07, 2007

Migrations chapter in AWD


The book shows an example of how to use data only migrations. The problem with this approach is that you have to write code for every table you want to populate. A better way to do it is to use the Rick Olsen's rake task found in the Beast source code.

This allows you to add data to any number of tables using just one task. It basically loads the data using fixtures. The fixture files are created under bootstrap folder in fixtures directory.

I still don't get it when the book has an example of irreversible migration and just raises the exception. What if I just want to continue migrating downwards without stopping at the irreversible migration?

Sunday, November 11, 2007

Restful Rails Development Book

Excellent book on RESTful Rails Development.
It has very good explanation of the RESTful Rails concepts. It's free. Check it out.

Saturday, November 10, 2007

Ruby Blocks Screencast Part 1

This screencast covers the basics of blocks in Ruby. It gradually builds on simple example and introduces the complicated concepts in a simple way. Duration : 17 mins. Dowload it here .

Domain Driven Design Quickly - Book Review

"According to Eric Evans, a domain model is not a particular diagram; it is the idea that the diagram is intended to convey. It is not just the knowledge in a domain expert's head; it is a rigorously organized  and selective abstraction of that knowledge. A diagram can represent and communicate a model, as can carefully written code, as can an English sentence."

A good domain model focuses only on the relevant details and ignores  the rest. There are several ways to communicate the model. The book explains some of the techniques covered by the book Domain Driven Design by Eric Evans.

They are :
  1.  Ubiquitous Language

  2.  Layered Architecture

  3.  Value Objects

  4.  Entity Objects

  5.  Aggregates

  6.  Services

  7.  Factories

  8.  Repositories
I am not going to explain them all here. You can download a
free copy of the book from info site. I will briefly go over some of them in the context of Rails
projects.

Ubiquitous Language


 We need to find those key concepts which define the domain and the design, and find corresponding words for them, and start using them. Some of them are easily spotted, but some are harder.

Aggregates


In the Code Review session by Marcel Molina and Jamis Buck Aggregates, they show an example where Aggregates is put into practice. They call the Aggregate as the Super Model.

I worked on a Rails project where the User model become bloated with attributes that could be extracted into its own model. For instance, address, contact info, billing info etc. So the User model is
an Aggregate.

Repositories


A good example would be ActiveRecord's find method, given an id it finds the record and returns an object that represents a row in the database.


Development Process and Domain Driven Design


"The Agile methods have their own problems and limitations; they advocate simplicity, but everybody has their own view of what that means. Also, continuous refactoring done by developers without solid design principles will produce code that is hard to understand or change."

I have experienced this on a project where the team was doing TDD and due to simplistic design the code was brittle. The team did not spend much time on design. It seemed like we were going back to
square one once every couple of weeks. The overall productivity of the team went down.

It talks about implicit concept, constraint, process and specification. It provides practical tips on how to refine and improve the initial domain model. I really liked this section of the
book.

Creating the Model


UML can lead to diagrams that are cluttered and hard to maintain. Creating a UML diagram to represent the whole system can result in a huge domain model.

The alternatives are :

1. Create a set of small diagrams with text that explains some aspect of the system which cannot be represented by the diagram. The diagrams can be hand drawn. In the initial stages the domain model
changes a lot, so this is a practical approach.

2. Communicate using code. This is the XP approach. Use well written code as the communication tool. In this case you don't have the problem of documents getting out of sync with the requirement
changes.

The book talks about the Analysis Model and the Design Model and how there is gap between these two models. The developers have to deal with the implementation issues that cannot be foreseen by the analysts.

Bounded Context


I learned this from Rails core team member Marcel Molina during the Advanced Rails studio. At that time I did not know it was explained in the Domain Driven Design book. The idea here is to create a
very cohesive model that is as small as possible.

If required, you can split your application into several applications that have its own domain model. For instance if you have a web application that is about outdoor adventure club management, you can split the billing system into a separate application. This allows the billing system to be used with any system.

I agree with other bloggers regarding the way the Rails team integrates those apps using ActiveResource. It is not a good solution. The ideal way to integrate them would be to use some kind of asynchronous messaging system. This could be as simple as a cron job.

Preserving Model Integrity


This chapter talks about large projects that consist of multiple teams. It describes how to go about applying domain driven design practices.

Conclusion


Domain driven design is not something new, it has been around for couple of decades or so. Eric Evans has documented them very well in his book. It is a must read for any developer regardless of whether you are part of a small or a big team.

In the last chapter where Eric Evans is interviewed he mentions the pitfalls of domain modeling:
  1.  Stay hands-on. Modelers need to code.

  2.  Focus on concrete scenarios. Abstract thinking has to be anchored in concrete cases.

  3.  Don't try to apply DDD to everything.
I remember an interview couple of years ago where the company that interviewed me was very interested in hiring me as a modeler. I never felt comfortable in just being a modeler without getting my hands dirty by writing some code. I am glad that I did not accept the offer, since they never allow a modeler to code.

Wednesday, November 07, 2007

Living on the Edge

1. rake rails:freeze:edge
2. rake rails:update

script/about output should show value for Edge Rails Version.

xml-simple gem was giving errors when script/about was run. It is used by aws-s3 gem. Uninstalled it for now.

Tuesday, November 06, 2007

Domain Driven Design

I attended the one day QCon Tutorial on Domain Driven Design by Eric
Evans. It was jam packed with real-world tips on dealing with software
complexity.

Introduction



In 1990's we were aiming for reuse, productivity and flexibility by
using object oriented systems. Here we are in 2007 and we still find
it elusive to achieve these in projects.

Eric said that his book was the result of analyzing several successful
projects and identifying the common elements in them. Those elements
do not guarantee success. There will be failures. The critical
complexity of most software projects is in understanding the domain
itself.

Experimentation - Fail Cheaply



Learn to brainstorm. It is cheap to fail at this stage. Go beyond the
first idea. Suggest two mutually exclusive ideas. This is a technique
to break out of the box. It allows us to explore the system beyond its
boundary.

So, look broader. Once we get a big picture we can zoom into the
smaller system that we are considering and come up with a better
solutions. The first idea can be a simple one.

Another way to fail cheaply is to prototype. Remember that is a throw
away so that the developer is free to make mistakes and does not have
to worry about doing it "The Right Way".

Terminology



Domain



The subject area to which the user applies a program is the "domain"
of the software.

Model



A model is a system of abstractions that describes selected aspects of
a domain and can be used to solve problems related to that domain. It
serves a particular use. It is NOT as realistic as possible. He gave
an interesting example of this: NASA uses Newton's principles, not
Einstein's even though it is a known fact that Einstein model is more
accurate. So it is useful relative to specific domain scenarios.

Ubiquitous Language



A language structured around the domain model and used by all team
members to connect all the activities of the team with the software.

Context



The setting in which a word or statement appears that determines its
meaning.,

Dealing with Clients and Resolving Impediments to Software Delivery


Core Vs Generic



Have you ever had the experience where you sit with a client and you
come up with a huge list of features for the software you are going to
develop? The client knows how to prioritize but do they know what is
essential in the domain that will satisfy their mission statement or
unique selling proposition?

Ask them:

1. What distinguishes your business from others?
2. What is your mission statement?

Use the answer as the criteria to find the core domain of the system
from the laundry list of features.

Generic things would be something that we could re-use and purchase
from a third-party. It could be used by your competition too, but the
core domain separates you from the rest. It gives you some kind of
competitive edge over your competitors.

Conclusion:



This is a must attend tutorial. I felt 3 days would have been ideal.
There is still lot to learn about domain driven design from the book.

Using RJS with Rails 2.0 Preview Release

1. Change the extension from rjs to .js.rjs
2. You must use the respond_to block (format.js will call the corresponding .js.rjs file)
3. Use link_to_remote or other remote calls to make the AJAX call.

Tuesday, October 23, 2007

Autocomplete in Rails 2.0

1. Install the auto_complete plugin.
script/plugin install http://svn.rubyonrails.org/rails/plugins/auto_complete
2. Turn off CSRF protection. Read Ryan's post.

You will get ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.3.7707/lib/action_controller/request_forgery_protection.rb:73

error if you don't turn it off.

Thursday, October 18, 2007

Testing Rails 2.0 Http Authentication

Peepcode Rails 2 - New features for your applications by Ryan Daigle shows one way of testing your controllers that use Rails 2.0 http authentication. Another way would be to use mocks. I will post an example when I get back from TDD with Rails training here in Columbus, Ohio.

Testing ActiveMerchant Billing

There are some good resources for ActiveMerchant billing plugin such as:

1. Processing Credit Cards
2. Active Merchant and AuthorizeNet
3. Active Merchant Thread
4. Good blog post on ActiveMerchant

Gotchas:

1. The transaction key that is provided by AuthorizeNet expires automatically in 24 hours. So you must recreate it. Login to your AuthorizeNet test account, go to settings -> Create a new Transaction key.

Use this your login id and the newly generated transaction key in the following code.

require File.dirname(__FILE__) + '/../test_helper'

class ActiveMerchantTest < Test::Unit::TestCase
include ActiveMerchant::Billing

def test_gateway
ActiveMerchant::Billing::Base.mode = :test

creditcard = ActiveMerchant::Billing::CreditCard.new(
:first_name => "dummy",
:last_name => "dummmy 2",
:number => "4779139500118580",
:verification_value => "410",
:type => "Visa",
:month => "10",
:year => "2008"
)

options = {
:name => "Bugs Bunny",
:email => "bbunny@gmail.com",
:phone => "4048615540",
:card_code => "410",
:order_id => "12345",
:description => "Conference reservation",
:billing_address => {
:address1 => "1234 Facke street",
:city => "Wichita",
:state => "Kansas",
:zip => "27606",
:country => "US" }
}
# If you do not immediately disable the old value, it will automatically expire in 24 hours.
gateway = AuthorizeNetGateway.new({:login => "Your API Login ID",
:password => "Your Transaction Key"})

response = gateway.purchase(10000, creditcard, options)

puts response.inspect
assert response.success?
end
end

The output response:

Response

Sunday, October 14, 2007

Extremely Simple Calendar Integration for Rails

Finally found a calendar that is very easy to install and use. Nice calendar. I had to change the width for the select in css to 60px, since I am displaying time also. The syntax:

<%= calendar_date_select_tag "event[departure]",
@event.departure.to_s,
:time => true %>

Upgrading Rails 1.2.5 version

ERROR: While executing gem ... (OpenURI ::HTTPError)
404 Not Found
To resolve this issue during upgrade:

1. sudo gem update --system

2. sudo gem install rails --include-dependecies

#2 worked when the server came back up.

Saturday, October 13, 2007

Testing Emails in Rails 2.0

There is a new assert_emails that can be used like:

assert_emails 1 do
UserMailer.deliver_signup_notification(@user)
end

There is also negated version : assert_no_emails that takes a block.

Friday, October 12, 2007

How to use alias for Textmate Rails projects

My ~/.bash_profile looks like this:

PATH="/usr/local/subversion/bin:$PATH"
PATH="/opt/local/bin:$PATH"
PATH="/usr/local/bin:/usr/local/sbin:/usr/local/mysql/bin:$PATH"
export PATH
PS1='\t:\w > '
export EDITOR='mate -w'
export JAVA_HOME=/usr
export MANPATH=$MANPATH:/opt/local/share/man
export INFOPATH=$INFOPATH:/opt/local/share/info

export atom="$HOME/work/atomizer"
export ard="$HOME/work/zepho/remote/trunk"
export astro="$HOME/clients/ge/astroceleb"
export star="$HOME/clients/ge/starstories"

alias matom="mate $atom"
alias mard="mate $ard"
alias mastro="mate $astro"
alias mstar="mate $star"
alias off="sudo shutdown -h now"

Example : matom opens the atomizer project.

How to configure Western Digital External Hard Disk for sharing on a network

1. Connect the WD MyBook to the Linksys router using USB cable.
2. Open the admin interface using the browser. In the Storage tab create a new share.
3. Make sure that All Partitions share is selected.
4. Open the finder and browse to the Network -> MsHome folder. Click on Linksyswrt350N and select the share that you created. Click ok. Now you can view the external drive from all the computers connected to the router.

Still have not figured out how to pick up the changes on the external drive from the computer that did change it. I have to reconnect to see the modifications. There has to be a better way.

How to setup mac ox for Facebook call back URL

1. Type ifconfig en0 in the terminal. The output will be like:

en0: flags=8863 mtu 1500
inet6 fe80::211:24ff:fed6:3436%en0 prefixlen 64 scopeid 0x4
inet AAA.XXX.Z.YYY netmask 0xffffff00 broadcast 192.168.1.255
ether 00:11:24:d6:34:36
media: autoselect (1000baseT ) status: active


2. Go to Linksys, Applications and Gaming tab, Port Range Forwarding and give a name for the application, specify start and end port (ex 3000 &B 3010), Protocol is both, To IP Address will have AAA.XXX.Z.YYY value, check the enabled box. Click on Save Settings.

3. In setup, DDNS tab, select DynDNS.org as the DDNS service and provide the username, password and hostname that you specified when you created an account with DynDNS.com site. System value is Capture(ddn.dynamic)Dynamic. All other values are default. Click Update and Save Settings.

4. Login to Facebook and specify the hostname and values for other parameters consistent with the above steps.

That's it. Now you can run the Facebook app and it will call your Rails app running on your machine.

Thursday, October 11, 2007

Tuesday, October 09, 2007

RSpec Not Implemented Feature

In the regular test unit, I do something like:

def test_load_upcoming_events_for_the_week
puts "Not Implemented : test_load_upcoming_events_for_the_week"
assert true
end

def test_load_top_4_categories
puts "Not Implemented : test_load_top_4_categories"
assert true
end

All my to do items goes into the autotest output and I have easy access to my to do list.

Integrating Flash With Rails

1. Install flashobject helper rails plugin
script/plugin install http://lipsiasoft.googlecode.com/svn/trunk/flashobject_helper

2. Include <%= javascript_include_tag :defaults %>

3. In the view: <%= flashobject_tag "/flash/demo.swf %>

Monday, October 08, 2007

Using Capistrano 1.4.1 when you already have 2.0

1. sudo gem install daemons gem_plugin mongrel mongrel_cluster --include-dependencies
2. sudo gem install capistrano -v 1.4.1
3. cap _1.4.1_ long_deploy

Sunday, October 07, 2007

Sake Headaches on Rails 2.0 Preview release

1. sudo gem install ruby2ruby -y
2. sudo gem install sake
3. sake -i bootstrap.rake

throws the error:

/usr/local/lib/ruby/gems/1.8/gems/sake-1.0.11/lib/sake.rb:315:in `parse': /usr/local/lib/ruby/gems/1.8/gems/rake-0.7.3/lib/rake.rb:2028:in `const_missing': uninitialized constant Sake::TasksFile::RAILS_ROOT (NameError)

RESTful authentication with Rails 2.0

1. script/generate authenticated user --include-activation creates Rails 1.2.3 style migration.

So, I changed it to:

class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users, :force => true do |t|
t.string :login, :email, :remember_token
t.string :crypted_password, :limit => 40
t.string :salt, :limit => 40
t.string :activation_code, :limit => 40

t.datetime :remember_token_expires_at, :activated_at
t.timestamps
end
end

def self.down
drop_table "users"
end
end

2. The routes.rb looks like:

ActionController::Routing::Routes.draw do |map|
map.resources :users
map.resource :session

map.connect '', :controller => 'home', :action => 'index'

map.with_options :controller => "users" do |page|
page.signup "/signup", :action => "new"
page.activate "/activate/:activation_code", :action => "activate"
end

# Install the default routes as the lowest priority.
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
end

I had to define named route for signup because if I use new_user method in the application.rhtml, I kept getting error.

I don't know how to define the route in a RESTful way for activation. So I have named route for it.

3. In the form:

<% form_for @user do |f| -%>

<% end -%>

That's it. I am able to signup and activate using Rails 2.0. Of course I had to rename the .rhtml files to .html.erb. Now the Textmate shortcuts are broken, since it recogizes only rhtml files.

Thursday, October 04, 2007

Avoid Heavy Response Processing in Rails

I am half-way through the Topfunky's Peepcode Code Review pdf book. It is very well written.

In my previous job, I had to find a way of processing records that was created by users and send them to an external vendor. My pointy haired boss told me to spawn a thread for this purpose. I suggested using some kind of messaging system for obvious reasons. In the end we compromised and settled for Rake task and cron job combination.

Peepcode's book talks about this issue in detail.

Tuesday, October 02, 2007

uninitialized constant Rails::Initializer::MemCache

1. sudo port install memcached
2. sudo gem install memcache-client

That got rid of the error message.

Friday, September 28, 2007

Intridea

I am excited to join forces with my friends in DC and work on some kick-ass Rails projects. Intridea has grown very fast in less than a year. Almost 15 Rails developers now.

I just ordered 30 inch Mac Cinema Display. I will be working from home, which will be fun and much more productive than going to an office. Finally no distractions and stupid meetings!!!

swf chart vs gruff

Need to evaluate them when I get some time. Requested Geoff to produce a screencast on Selenium on Rails. He responded back after a few days saying he has to learn it and has included it in this todo list.

Ruby Idioms Presentation

Here is the link to the presentation. Thanks to Pelle for his review on his website.

Thursday, September 20, 2007

How to use Will Paginate 2.0 Rails plugin

Step 1: In the controller:
@users = User.paginate(:order => 'created_at DESC'
:conditions => ["active = ?", 1]
:per_page => 10,
:page => params[:page])

Step 2: In the view:
<%= will_paginate @users, :inner_window => 10, :outer_window => 10 %>

This will create page links from 1 to 10 then dots followed by numbered links for last 10 pages.

Step 3: To make the pagination links sexy, copy the following CSS (Digg style):

div.pagination {
padding: 3px;
margin: 3px;
}

div.pagination a {
padding: 2px 5px 2px 5px;
margin: 2px;
border: 1px solid #AAAADD;

text-decoration: none; /* no underline */
color: #000099;
}
div.pagination a:hover, div.pagination a:active {
border: 1px solid #000099;

color: #000;
}
div.pagination span.current {
padding: 2px 5px 2px 5px;
margin: 2px;
border: 1px solid #000099;

font-weight: bold;
background-color: #000099;
color: #FFF;
}
div.pagination span.disabled {
padding: 2px 5px 2px 5px;
margin: 2px;
border: 1px solid #EEE;

color: #DDD;
}

Reference: Err the blog.

Tuesday, September 18, 2007

San Francisco Ruby Meetup

I presented my Ruby Idioms today at the San Francisco Ruby Meetup. It was my first presentation and I was very excited. It was full of examples and practical tips. Some of the idioms were described in the context of Rails applications. Soon I will be posting the link to the actual presentation in pdf format. Enjoy!

Tuesday, August 28, 2007

Rails Performance Notes

Static Caching

- Cache on demand through Rails
- Cron sweeper (minute.rb?)
- JS + cookie for username
- Caching functional test
- ngnix config (run it locally for testing?)
- deploying cron job


Performance

1. Query optimization - query analysis (doing n queries instead of joins)
2. Rails static page caching
3. Asset packager - Firebug Net tab (Page lead times, "apparent" performance)
4. Number of optimal Mongrels ( Topfunky screencast )
5. Rails log - Page load times, Query times
6. Unix diagnostics
- Top
- Vmstat
- MySQL tools
- tail / grep etc
7. Periodic reporting
8. Benchmarks

Friday, August 17, 2007

PostgreSQL on Mac OS

MySQL suddenly stopped working and I was not able to run it. I got frustrated with MySQL error messages like no /tmp/mysql.sock found and -bash: /usr/local/mysql/bin/mysql: Bad CPU type in executable

22:04:59:/usr/local/src > mkdir postgres
22:05:24:/usr/local/src > cd postgres/
22:05:27:/usr/local/src/postgres > ls -l
22:05:29:/usr/local/src/postgres > curl -O ftp://ftp5.us.postgresql.org/pub/PostgreSQL/source/v8.2.4/postgresql-8.2.4.tar.gz
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 14.8M 100 14.8M 0 0 48521 0 0:05:21 0:05:21 --:--:-- 77126
22:12:19:/usr/local/src/postgres > tar -xzvf postgresql-8.2.4.tar.gz
postgresql-8.2.4

22:31:26:/usr/local/src/postgres > cd postgresql-8.2.4
22:31:30:/usr/local/src/postgres/postgresql-8.2.4 > ./configure --with-includes=/sw/include/ --with-libraries=/sw/lib
checking build system type... powerpc-apple-darwin8.10.0

22:33:12:/usr/local/src/postgres/postgresql-8.2.4 > make
22:41:07:/usr/local/src/postgres/postgresql-8.2.4 > sudo make install
23:25:46:/usr/local/src/postgres/postgresql-8.2.4 > /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data

WARNING: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the -A option the
next time you run initdb.

Success. You can now start the database server using:

/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data
or
/usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data -l logfile start

23:29:07:/usr/local/src/postgres/postgresql-8.2.4 > /usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data
LOG: database system was shut down at 2007-08-16 23:26:25 PDT
LOG: checkpoint record is at 0/42BEB8
LOG: redo record is at 0/42BEB8; undo record is at 0/0; shutdown TRUE
LOG: next transaction ID: 0/593; next OID: 10820
LOG: next MultiXactId: 1; next MultiXactOffset: 0
LOG: database system is ready

23:35:06:~ > /usr/local/pgsql/bin/createdb
CREATE DATABASE
23:35:33:~ > /usr/local/pgsql/bin/createdb mytestdb
CREATE DATABASE
23:35:45:~ > /usr/local/pgsql/bin/psql mytestdb
Welcome to psql 8.2.4, the PostgreSQL interactive terminal.

Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit

mytestdb=# create table foo(name varchar primary key, foo_id serial);
NOTICE: CREATE TABLE will create implicit sequence "foo_foo_id_seq" for serial column "foo.foo_id"
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "foo_pkey" for table "foo"
CREATE TABLE
mytestdb=# insert into foo(name) values ('Liz');
INSERT 0 1
mytestdb=# insert into foo(name) values ('Bunny');
INSERT 0 1
mytestdb=# select * from foo;
name | foo_id
-------+--------
Liz | 1
Bunny | 2
(2 rows)

Sunday, August 12, 2007

Acts as Billable Installation

1. script/plugin install http://source.collectiveidea.com/public/acts_as
_billable/trunk/

2. script/plugin install http://activemerchant.googlecode.com/svn/trunk/
active_merchant

3. sudo gem install --source http://dist.leetsoft.com money

4. script/plugin install http://source.collectiveidea.com/public/rails/p
lugins/acts_as_money

Monday, July 30, 2007

How to add Rails plugin files to SVN during install

use -x flag. Example:

script/plugin install -x http://svn.techno-weenie.net/projects/plugi
ns/restful_authentication/

Tuesday, July 24, 2007

Recurring Billing in Rails

Research notes:

Dealing with subscriptions payment
Follow-up to subscriptions
Recharging to the Same Credit Card

Sample test case:

def test_reference_purchase
assert response = @gateway.purchase(Money.new(10000), @creditcard, @options)
assert_equal "Approved", response.message
assert response.success?
assert response.test?
assert_not_nil pn_ref = response.authorization

# now another purchase, by reference
assert response = @gateway.purchase(Money.new(10000), pn_ref)
assert_equal "Approved", response.message
assert response.success?
assert response.test?
end

Acts As Billable Plugin

script/plugin install http://source.collectiveidea.com/public/acts_as_billable/trunk/
There’s a start of a sample app (that uses rspec) that goes with it at http://source.collectiveidea.com/public/acts_as_billable/samples/depot

Authorize.Net Automated Recurring Billing (ARB) Example Code

ARG Guide

Tuesday, July 17, 2007

Help in writing tests in Rails

script/console test

It will load the console in the test environment. Very useful to experiment with the code and write tests.

Saturday, July 14, 2007

Railscookbook example error

NameError in User#list_perms

Showing app/views/user/list_perms.rhtml where line #22 raised:

uninitialized constant UserHelper::Permission

create the permission model without migration.

Also the migration for permissions table does not have a id column. This results in a bug where the update does not work for some cases. So I had to add a primary key column to the permissions table. This fixed the buggy update problem.

How to skip migration in Rails

use --skip-migration switch: Ex: script/generate model user --skip-migration

Thursday, July 05, 2007

How to suppress rendering of layout while generating xml in Rails

def my_xml_method
@foo = Foo.find(:all)
render :layout => false
end

If you have render and respond_to in the same method, you will get the dreaded double render error.

Wednesday, July 04, 2007

How to install RubyInline in Mac OS

$ sudo gem install rubyinline
Successfully installed RubyInline-3.6.3
Installing ri documentation for RubyInline-3.6.3...
Installing RDoc documentation for RubyInline-3.6.3...

Port install did not work:

sudo port install rb-rubyinline
---> Fetching autoconf
---> Attempting to fetch autoconf-2.61.tar.bz2 from http://ftp.gnu.org/gnu/autoconf
---> Verifying checksum(s) for autoconf
---> Extracting autoconf
---> Configuring autoconf
---> Building autoconf with target all
---> Staging autoconf into destroot
---> Installing autoconf 2.61_0
---> Activating autoconf 2.61_0
---> Cleaning autoconf
---> Fetching rb-rubygems
---> Attempting to fetch rubygems-0.9.4.tgz from http://rubyforge.org/frs/download.php/20989/
---> Verifying checksum(s) for rb-rubygems
---> Extracting rb-rubygems
---> Configuring rb-rubygems
Error: Target com.apple.configure returned: configure failure: shell command " cd "/opt/local/var/db/dports/build/_opt_local_var_db_dports_sources_rsync.rsync.darwinports.org_dpupdate_dports_ruby_rb-rubygems/work/rubygems-0.9.4" && /opt/local/bin/ruby -rvendor-specific setup.rb config " returned error 127
Command output: sh: line 1: /opt/local/bin/ruby: No such file or directory

Error: The following dependencies failed to build: rb-hoe rb-rake rb-rubygems rb-rubyforge
Error: Status 1 encountered during processing.

How to use select_tag to create drop down menus in Rails

<%=
select_tag :size, options_for_select(["Small", "Medium", "Large"])
%>

This will create a drop down with the values in the array. You can either declare a constant array in the model and use that like: MyModel::SHIRT_SIZES instead of hard coding it. If it is database driven, write a helper that will return an array of options.

Sunday, July 01, 2007

How to find the helper methods for RESTful nested routes in Rails


1) script/console
2) >> irb ActionController::Routing::Routes
3) rs = ActionController::Routing::Routes
4) rs.named_routes.each {|name, route| puts( name, route) }; 1
5) Just copy the list of helper methods show in the output of step 4 and append path to that name. You must also provide the required ids shown in the output. For example take the output:

user
GET /users/:id/ {:action=>"show", :controller=>"users"}

and in the console, type:

>> user_path 1
=> "/users/1"

The same process can be used for nested routes.

Reference: Rails Routing by David A Black. This book gave me a solid understanding of routes.

Friday, June 29, 2007

Difference between capitalize and humanize in Rails

From the script/console:

>> t = "test"
=> "test"
>> t.capitalize
=> "Test"
>> t.humanize
=> "Test"
>> c = "foo bar"
=> "foo bar"
>> c.humanize
=> "Foo bar"
>> c.capitalize
=> "Foo bar"

How to use hidden field in Rails

<%= f.hidden_field :user_id, :value => current_user.id %>

This passes a hidden variable user_id with the value of current_user.id

Thursday, June 28, 2007

Displaying time only in Rails

Not well documented in the Rails API. Here it is:

<%= f.datetime_select(:time, :discard_day => true, :discard_month => true, :discard_year => true) %>

How to create admin accounts in Rails app

The Memphisto source has rake db:bootstrap task that I use for loading admin users into the database. The dynamic fixture allows using any user and password for a admin account.

Wednesday, June 27, 2007

How to freeze gems using Rake

1. script/plugin install http://svn.ardes.com/rails_plugins/gems
2. rake gems:freeze GEM=gem_name

Monday, June 25, 2007

Migrating Local Subversion Repository to Remote Repository

I have been developing the Rails app on my Powerbook using Subversion with file:/// protocol. So when I had to migrate it to Subversion repository hosted remotely by Rimu I had to do the following:

1) On the laptop:

svnadmin dump ~/home/path/to/svn/repos > some-file-name

2) I used Transmit FTP client to use SFTP to the remote host and copied the some-file-name to the remote machine.

3) Login to the remote machine and run:

svnadmin load subversion-repo-name < some-file-name

I created a new directory on my laptop and did a checkout from remote repository:
svn co --username some_user --password some_password http://www.your-domain.com/project_name/trunk

then svn info shows that the repository is http:// pointing to the remote repository.

svn log http://www.your-domain.com/project_name/trunk

shows all the log messages. Note this did not show all the 10 revisions that I had on my local repository. It showed only the changes that I had made after the migration. So the local repository version was at 10 but the remote repository was moving from version 3.

Debugging Rails App in Realtime with the breakpointer

1) include the line: breakpoint "some description goes here" where you want the program execution to stop.
2) From the rails app root directory run: script/breakpointer
3) Fire the browser and let the app hit the breakpoint, you will be taken to the >> prompt where you can examine variables.

This helped me to customize the Attachment_fu plugin so that image upload is optional.

Saturday, June 23, 2007

Testing XML output in Rails

1. get :action_name, :format => "xml", :id => 1
2. content = @response.body
3. assert_select "title", :text => "Rails Recipes"

The above steps basically simulate http://localhost:3000/xmlcontroller/action_name/1.xml.

Let's say you have multiple records in the xml output you can check:

assert_select "book", :count => 2

In this case there will be two books in xml output.

Thursday, June 21, 2007

.svn: Commit failed

Error:
.svn: Commit failed (details follow):
svn: Out of date: 'vendor/plugins' in transaction '7-1'
svn: Your commit message was left in a temporary file:
svn: '/Users/myprojects/svn-commit.tmp'

svn up first and then svn delete on the files that is no longer required and then commit.

Send Method in Ruby

When you have an object, you can set the values for its attributes by:

obj.send(#{attribute}, value) where attribute is the actual attribute while looping through an array of strings that contains the attribute names. The value is the actual value that is used to initialize the attribute.

Wednesday, June 20, 2007

Recursion in Ruby

Calculate x to the power of y using recursion.

def test(x, y)
if (y == 0)
return 1
else
test(x, y-1) * x
end
end

puts test(2,3)

This was a interesting question during the interview. I never understood recursion. The interviewer skillfully provided some clues for me to figure this one out myself. I wrote down some sample values for x and y in a tabular format. Worked through the problem and surprisingly come up with the right answer!

Tuesday, June 19, 2007

No such file or directory - /tmp/501/nl.uu.phil.SSHAgent.socket (Errno::ENOENT)

I was hacking with passwordless ssh login when Capistrano deployment failed with that message. Running (on Mac OS):

$ ssh-agent bash
$ ssh-add

and then running cap tasks fixed the problem for now.

Monday, June 18, 2007

Using acts_as_reportable Rails plugin to generate CSV data from Active Record

1) sudo gem install ruport -y
2) require "ruport" in environment.rb
3) include acts_as_reportable in your model.

You are now ready to play with the model in the script/console. Very easy and powerful plugin. For more info, check out http://stonecode.svnrepository.com/ruport/trac.cgi/wiki/AARTutorial

Upgraded Ruby to Ruby 1.8.6-p36

This version is compatible with FasterCSV. Hivelogic instructions will work, but you need to use the the url ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.6-p36.tar.gz
to install the latest Ruby distribution. This release was announced on Ruby-Talk mailing list.

You can skip the readline installation if you have it already installed for Ruby 1.8.6 released on march 07.

4 Useful Rails Plugins

PDF Plugin
Calendar Helper Plugin:
Active Record Extensions:
Acts As Reportable

Sunday, June 17, 2007

Pending Deployment Tasks

1) Find out how deploy_with_migrations Capistrano switch works.
2) Change the style.css for the site.
3) How to connect to the database during deployment without using database.yml?
4) How to upgrade if you freeze gems?

This is answered in Rails Recipes. 5) Install Exception Notification plugin and SiteMeter.
6) Contact model, create a secure RSS feed. Refer Rails Recipes.

Deployed Rails App on Staging and Production Environments

1) I looked at the mongrel.log file, the error message said that it
could not find staging.rb. So I created an empty staging.rb file under
config/environments directory.

2) staging configuration for socket value was set to the output of
locate mysql.sock.

3) The staging.log showed that require 'turn' statement in
environment.rb was missing the turn gem. I moved this statement to
development.rb, since it is required only for development.

Missing gem headaches: I also learned about rake freeze gem that allows
taking gems to the deployment environment. But I don't know if I freeze
a gem I will be able to upgrade it later. I will get this clarified from
Rails mailing list.

My emails are being sent, but when I signup I see the link as:

http://localhost.localdomain/activate/7fb260146d37cf5aec957fa0662d94c52a9f2488

http://#{ActionMailer::Base.smtp_settings[:domain]}/activate/#{user.activation_code} line in the rhtml template takes the smtp_settings defined for that environment. So
define the domain in staging.rb to fix this problem

Saturday, June 16, 2007

`No such file or directory – /tmp/mysql.sock`

run `locate mysql.sock` or `locate mysqld.sock` to find where your socket is located, then update database.yml to reflect your system’s configuration. So your entry will be:

socket: /path/to/mysql.sock

Friday, June 15, 2007

Simply Rich Association Plugin Released

I am excited to make my first plugin available for public. You can
checkout the code by doing:

svn checkout http://simply-rich-association.googlecode.com/svn/trunk/
simply-rich-association



Hosted on Google Code: Project home page is http://code.google.com/p/simply-rich-association/

The README file has good explanation of what the plugin can do. http://simply-rich-association.googlecode.com/svn/trunk/README
Enjoy!

Wednesday, June 13, 2007

Komodo IDE 4.1 First Impression

When you run the Komodo it loads all the code intelligence for PHP, Python etc. Very annoying when you want to just work on Ruby. After installation the tutorial instructions tell you to load a certain file. Uhh? Where did it install? It does not know where it installed so you have to manually search to load the tutorial.

There is no way to customize the appearance, no themes. No thanks, I will stick with Textmate for now. Maybe Netbeans might be a good alternative one day.

How to convert a name of a class to Class in Ruby

"Foo".constantize will return Foo. Now you can call any methods on Foo.

Attachment_fu - How to display the image

Mike clark's weblog has a good article on how to use attachment_fu to upload images. In my application I did not need any thumbnails. In this case to display the image in the show.rhtml I had to use the image_tag(@person.public_filename) to display the image.

Adding multiple files to Subversion at once

svn st | grep "^?" | awk '{ print $2}' | while read f; do svn add $f; done

If you want all the ? files to be added. Found this tip here http://www.gregwhitescarver.com/blog/2006/05/22/add-multiple-files-in-subversion-at-once/

Creating admin accounts using Rake task

Memphisto project by Rick Olson has a Rake task called db:bootstrap that is in bootstrap.rake file. It creates admin accounts from the data specified in the users.yml file. Awesome!!!

How to export data from one database and import into another.

mysqldump -u root -p myapp_staging some_table > mytable.sql

and then

mysql -u root -p myapp_acceptance < mytable.sql

Rails Refactoring to Resources - Using CRUD and REST in Your Rails Application

Nice book from Apress written by Trotter Cashion. I finished reading this book last night. It has a very good coverage of the RESTful goodness in Rails. Short and sweet. Learned a lot from this book. Very well written. I give it 4.5 out of 5 stars. The reason is ActiveResource in the latest Rails is not discussed in the book.

Saturday, June 09, 2007

svn: Out of date: '/trunk' in transaction '2-1

When I commit the changes to the svn, I got:
svn ci .
Sending .
svn: Commit failed (details follow):
svn: Out of date: '/trunk' in transaction '2-1'
svn: Your commit message was left in a temporary file:
svn: '/Users/balaparanj/work/zepho/ard/svn-commit.tmp'

Out of date here means the repository version is not the same as the local version. It works after doing svn up.

Tuesday, May 15, 2007

Rails Performance Screencast notes

Here is the notes I took notes from topfunky's httperf screencast.

Production Log Analyzer is a gem that lets you find out which pages on
your site are dragging you down.

Change one thing at a time and benchmark. Take actual data from
production db, export it and use it for benchmarking. Create a
separate environment for benchmarking.

Install httperf. Need 2 machines one for running httperf client and
the other for running Rails app.

Shut down all unnecessary programs on both machines to reduce CPU
usage. This reduces unpredictable results.

Process for Benchmarking Webapplication using Httperf

1) rake sweep_cache
2) mongrel_rails start -e production (no logging)
3) Hit a particular page once
4) run httperf (with consistent args)

Step 1 and 2 is run on Rails app machine. Go to browser on the client
machine load the page and run:

httperf --server machine_name --port 3000 --ur /page_name --num-conns 1000

The number of connections parameter can be changed. In the output of
the httperf make sure that you get number of replies is same as total
connections. Reply status should not have any errors. If there are any
httperf errors the results must be tossed out.

Copy the "Reply rate" line of the httperf output for different number
of connections and use topfunky's script to generate graphs.

./script/parse_httperf_log log/httperf-sample-log.txt

Tuning Mongrel for Performance

Here are the steps for finding how many requests per second a single
Mongrel process can handle.

httperf --server machine_name --uri /page_name --port 3000 --num-conns
7000 --rate 650 --hog

650 is the requests/sec

If this process hangs for more than 20 secs then we have overloaded
Mongrel. Httperf should have no errors (because it means httperf was
overloaded, in that case data must be tossed out).

Try different values for number of connections and rate, such as 6600,
660, 6700, 670 etc. Till the reply rate reaches a maxium and begins to
drop off.

Scaling Rails - Notes from Silicon Valley Ruby on Rails Meetup

Some websites are launched by getting it on TechCrunch, Digg, Reddit
etc. In such cases there is no time to grow organically.

Resources:

1. The Adventures of Scaling Rails -
http://poocs.net/2006/3/13/the­adventures­of ­scaling­stage­1
2. Stephen Kaes "Performance Rails" - http://railsexpress.de/blog/f
iles/slides/rubyenrails2006.pdf
3. RobotCoop blog and gems -
http://www.robotcoop.com/articles/2006/10/10/the­sof
tware­and­hardware­that­runs­our­sites
4. OReilly's book "High Performance MySQL

This presentation's focus is on what's different from previous
writings. For comprehensive overview refer the above resources.

Scribd.com was in launched in march, 07. It is the "YouTube" for
documents and it handles around 1 Million requests per day.

Current Scribd Architecture

1 Web Server
3 Database Servers
3 Document Conversion Servers
Test and Backup machines
Amazon S3

Server Hardware

Dual, dual core woodcrests at 3 Gz
16 GB of memory
4 15K SCSCI hard drives in a RAID 10
Disk speed is important. Don't skimp; you're not Google, and it's
easier to scale up than out.
Hosted by Softlayer.

Software

CentOS
Apache/Mongrel
Memcached, RobotCoop's memcache-client
Stefan Kaes' SQLSessionStore - This is the best way to store peristent sessions.
Monit, Capistrano
Postfix

They ran tests and found out that fragment caching improved
performance for their web app.

How to Use Fragment Caching

Consider only the most frequently accessed pages.
Look for pieces of the page that don't change on every page view and
are expensive to compute

Just wrap them in a
<% cache('keyname') do %>
...
<% end %>
Do timing test before and afterwards; backtrack
unless significant performance gains

Expiring fragments - 1. Time based

Use memcached for storing fragments
It gives better performance
It is easier to scale to multiple servers
Most importantly: It allows time­based expiration

Use plugin http://agilewebdevelopment.com/plugins/memcache_fragments_with_time_e...
Dead easy:
<% cache 'keyname', :expire => 10.minutes do %>
...
<% end %>

Expiring fragments - 2. Manually

No need to serve stale data
Just use: Cache.delete("fragment:/partials/whatever")
Clear fragments whenever data changes
Again, easier with memcached

They also discussed about how to use 2 database servers with Rails
app. For more information you can see the slides at
http://www.scribd.com/doc/49575/Scaling-Rails-Presentation

Q & A

They use SWF open source plugin for uploading documents (it allows
multiple docs to be uploaded simultaneously)

They pay only $100 monthly for Amazon S3 for 5 tera bytes of b/w
usage. Downside of using Amazon S3 is that they cannot generate
analytics for that part of the app.

The uploaded files goes to a queue and is processed in the background.
So the documents don't appear immediately on the site if the load is
high.

Tip from the first presentation on CacheBoard: It uses backgroun drb
plugin by Ezra for exporting documents in XML format.

Tuesday, May 01, 2007

Configuring Selenium to Run Automated Tests

Had to dig out this buried info on Selenium to get the browser to run the automated tests.

Also the Selenium tests are not independent of each other. The tests within a particular file depend on what page the previous test has ended. Strange but if you don't know this you will end up spending lot of time banging your head against the wall.

Colorizing ZenTest output

To get the green and red color for autotest:

1. sudo gem install --remote Redgreen
2. put the statement: require 'redgreen' in the environment.rb

restart the autotest if is already running. Now you will have green color for passing scenario and red for failing tests. Enjoy!

Monday, April 30, 2007

Tests : Before

21:32:17:~/clients/brep/td/trunk > rake stats
(in /Users/balaparanj/clients/brep/td/trunk)
/Users/balaparanj/clients/brep/td/trunk/config/boot.rb:38:Warning: require_gem is obsolete. Use gem instead.
+----------------------+-------+-------+---------+---------+-----+-------+
| Name | Lines | LOC | Classes | Methods | M/C | LOC/M |
+----------------------+-------+-------+---------+---------+-----+-------+
| Controllers | 1158 | 972 | 28 | 118 | 4 | 6 |
| Helpers | 329 | 283 | 0 | 42 | 0 | 4 |
| Models | 975 | 759 | 25 | 127 | 5 | 3 |
| Libraries | 733 | 552 | 9 | 82 | 9 | 4 |
| Components | 0 | 0 | 0 | 0 | 0 | 0 |
| Integration tests | 0 | 0 | 0 | 0 | 0 | 0 |
| Functional tests | 701 | 522 | 52 | 106 | 2 | 2 |
| Unit tests | 493 | 382 | 26 | 62 | 2 | 4 |
+----------------------+-------+-------+---------+---------+-----+-------+
| Total | 4389 | 3470 | 140 | 537 | 3 | 4 |
+----------------------+-------+-------+---------+---------+-----+-------+
Code LOC: 2566 Test LOC: 904 Code to Test Ratio: 1:0.4

ssh: somedomain.org: No address associated with nodename

This error message happened while remote login using ssh. ping command did not work. The problem was the domain was incorrect.

Saturday, April 28, 2007

Ruby: No such file to load -- ubygems (LoadError)

I deleted the contents of directory site_ruby and I was getting that error message. After some googling found Rich Kilmer's reply

"You have installed rubygems and set the RUBYOPT variable. This is the
downside to using the RUBYOPT :-(

Just unset that variable and then you should be good to go."

-rich

Thanks Rich, that fixed my problem.

rmagick headache on mac os

Finally resolved the rmagick installation problems. The actual problem was not rmagick itself but a custom script in my project.

I found the RMagick install script for Mac OS X - Version 0.2.0
on rmagick installation faq.

/opt/local/bin/ruby: bad interpreter:

I was getting the weird ruby bad interpreter error message after I deleted everything under site_ruby directory. I was working on getting the rmagick working on my laptop. I resolved the problem by reinstalling the Ruby 1.8.6 and Rubygems 0.9.2.

Friday, April 27, 2007

warning: multiple values for a block parameter (0 for 1)

In the following irb session the error message indicates that the input parameter is missing.

>> hello = lambda { "hello" }
=> #
>> hello.call
=> "hello"
>> log = lambda { |str| puts "[LOG] #{str}" }
=> #
>> log.call
(irb):16: warning: multiple values for a block parameter (0 for 1)
from (irb):17
[LOG]
=> nil
>> log.call("A test log message")
[LOG] A test log message
=> nil

Friday, April 20, 2007

Capistrano Concepts

Chris Selmer's Capistrano Presentation from the April 5, 2007 DCRUG
meeting is very good.

The Rails Edge conference had discussion on the material
covered in this presentation, but this presentation connected all the
dots for me.

Copying to the clipboard in UNIX

You can send any output to the clipboard by using pbcopy. For example: history | pbcopy will send the output of history command to the clipboard. You can just paste it in email or other document. Very nice. pbpaste will paste the contents of the clip board.

Tuesday, March 20, 2007

How to create drop down boxes in Ruby on Rails

Migration file : 001_create_people.rb

class CreatePeople < ActiveRecord::Migration
def self.up
create_table :people do |t|
t.column :first_name, :string
t.column :last_name, :string
t.column :email, :string
t.column :created_at, :datetime
end
end

def self.down
drop_table :people
end
end

person.rb
class Person < ActiveRecord::Base
has_many :tasks
end

task.rb
class Task < ActiveRecord::Base
belongs_to :user

def self.find_all_person
Person.find(:all, :order => "first_name").map {|u| [u.first_name, u.id] }
end

end

tasks/_form.rhtml

<h2> Create a Task for a Person</h2>
<% form_for ( :task, :url => path, :html => { :method => method } ) do |f| %>
    <p>
    
Title:        <br>
        <%= f.text_field :title, :class => 'text_field' %><br>
    </p>
    <p>
    
Content:
        <br>
        <%= f.text_field :content, :class => 'text_field' %><br>
    </p>

        <br>
        
        <p>Select a priority:
    
          <%= f.select ( :priority, %w { 1 2 3 4 5 6 7 8 9 10 } ) %>
    
        </p>
    </p>

    Person:
            <br>
            <%=
             f.select ( :people_id, @people )
            %>

        </p>
    
    <p>
        <%= submit_tag button_text %>
    </p>

<% end %>

tasks/edit.rhtml
<h1>Editing task</h1>

<%= error_messages_for :task %>

<% form_for ( :task, :url => task_path ( @task ) , :html => { :method => :put } ) do |f| %>
  <p>
    <%= submit_tag "Update" %>
  </p>
<% end %>

<%= link_to 'Show', task_path ( @task ) %> |
<%= link_to 'Back', tasks_path %>

tasks/index.rhtml
<h1>Listing tasks</h1>

<table>
  <tr>
  </tr>
  
<% for task in @tasks %>

<tr>
    <td><%= link_to   ( h task.title ) ,    task_path ( task ) %></td>
  </tr>

<% end %>
</table>

<br />

<%= link_to 'New task', new_task_path %>

tasks/new.rhtml
<h1>New task</h1>

<%= error_messages_for :task %>

<%= render :partial => 'form', :locals => { :path => tasks_path,
                                              :method => :post,
                                              :button_text => 'Create' } %>
                                            

<%= link_to 'Back', tasks_path %>

tasks/show.rhtml

<h2>Task </h2>
    <p> Title: <%=  h @task.title %></p>
    <p>Content: <%= h @task.content %></p>
    <p>Priority: <%= h @task.priority %></p>
    <p>Created At: <%= @task.created_at %></p>
    <p>Person: <%=  @person.first_name %></p> -->
    
<%= link_to 'Back', tasks_path %>

people/_form.rhtml

<% form_for ( :person, :url => path, :html => { :method => method } ) do |f| %>
    <p>
    
    <strong>First Name: </strong>
        <br>
        <%= f.text_field :first_name, :class => 'text_field' %><br>
    </p>
    <p>
    
    <strong>Last Name: </strong>
        <br>
        <%= f.text_field :last_name, :class => 'text_field' %><br>
    </p>

    <strong>Email: </strong>
        <br>
        <%= f.text_field :email, :class => 'text_field' %><br>
    </p>

    <p>
        <%= submit_tag button_text %>
    </p>

<% end %>

people/edit.rhtml
<h1>Editing person</h1>

<%= error_messages_for :person %>

<%= render :partial => 'form', :locals => { :path => person_path ( @person ) ,
                                            :method => :put,
                                            :button_text => 'Update' }
%>


<%= link_to 'Show', person_path ( @person ) %> |
<%= link_to 'Back', people_path %>

people/index.rhtml
<h1>Listing people</h1>
* Create an application to track a person's tasks. The user should be able to
create people, create tasks, and assign a task to a person when the task is created.

<table>
  <tr>
  </tr>
  
<% for person in @people %>
<tr>
    <td><%= link_to   ( h person.first_name ) ,    person_path ( person ) %></td>
  </tr>
  
<% end %>
</table>

<br />

<%= link_to 'New person', new_person_path %>

people/new.rhtml
<h1>New person</h1>

<%= error_messages_for :person %>

<%= render :partial => 'form', :locals => { :path => people_path,
                                              :method => :post,
                                              :button_text => 'Create' } %>


<%= link_to 'Back', people_path %>

people/show.rhtml

<h2>Person </h2>
    <p>First Name: <%=  h @person.first_name %></p>
    <p>Last Name: <%= h @person.last_name %></p>
    <p>Last Name: <%= h @person.email %></p>

<%= link_to 'Edit', edit_person_path ( @person ) %> |
<%= link_to 'Back', people_path %>

home/index.rhtml
<%= link_to  "People",    :controller => :people, :action => :index %><br>
<%= link_to  "Tasks",    :controller => :tasks, :action => :index %>

layouts/people.rhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
  <title>People: <%= controller.action_name %></title>
  <%= stylesheet_link_tag 'scaffold' %>
</head>
<body>

<p style="color: green"><%= flash[:notice] %></p>

<%= yield  %>

</body>
</html>

layouts/tasks.rhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
  <title>Tasks: <%= controller.action_name %></title>
  <%= stylesheet_link_tag 'scaffold' %>
</head>
<body>

<p style="color: green"><%= flash[:notice] %></p>

<%= yield  %>

</body>
</html>

controllers/home_controller.rb
class HomeController < ApplicationController
def index

end
end

people_controller.rb
class PeopleController < ApplicationController
# GET /people
# GET /people.xml
def index
@people = Person.find(:all)

respond_to do |format|
format.html # index.rhtml
format.xml { render :xml => @people.to_xml }
end
end

# GET /people/1
# GET /people/1.xml
def show
@person = Person.find(params[:id])

respond_to do |format|
format.html # show.rhtml
format.xml { render :xml => @person.to_xml }
end
end

# GET /people/new
def new
@person = Person.new
end

# GET /people/1;edit
def edit
@person = Person.find(params[:id])
end

# POST /people
# POST /people.xml
def create
@person = Person.new(params[:person])

respond_to do |format|
if @person.save
flash[:notice] = 'Person was successfully created.'
format.html { redirect_to person_url(@person) }
format.xml { head :created, :location => person_url(@person) }
else
format.html { render :action => "new" }
format.xml { render :xml => @person.errors.to_xml }
end
end
end

# PUT /people/1
# PUT /people/1.xml
def update
@person = Person.find(params[:id])

respond_to do |format|
if @person.update_attributes(params[:person])
flash[:notice] = 'Person was successfully updated.'
format.html { redirect_to person_url(@person) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => @person.errors.to_xml }
end
end
end

# DELETE /people/1
# DELETE /people/1.xml
def destroy
@person = Person.find(params[:id])
@person.destroy

respond_to do |format|
format.html { redirect_to people_url }
format.xml { head :ok }
end
end
end

controllers/tasks_controller.rb
class TasksController < ApplicationController
# GET /tasks
# GET /tasks.xml
def index
@tasks = Task.find(:all)

respond_to do |format|
format.html # index.rhtml
format.xml { render :xml => @tasks.to_xml }
end
end

# GET /tasks/1
# GET /tasks/1.xml
def show
@task = Task.find(params[:id])
@person = Person.find(:first, :conditions => "id = #{@task.people_id}")

respond_to do |format|
format.html # show.rhtml
format.xml { render :xml => @task.to_xml }
end
end

# GET /tasks/new
def new
@task = Task.new
@people = Task.find_all_person
end

# GET /tasks/1;edit
def edit
@task = Task.find(params[:id])
end

# POST /tasks
# POST /tasks.xml
def create
@task = Task.new(params[:task])
@person = Person.find(:first, :conditions => "id = #{@task.people_id}")

respond_to do |format|
if @task.save
flash[:notice] = 'Task was successfully created.'
format.html { redirect_to task_url(@task) }
format.xml { head :created, :location => task_url(@task) }
else
format.html { render :action => "new" }
format.xml { render :xml => @task.errors.to_xml }
end
end
end

# PUT /tasks/1
# PUT /tasks/1.xml
def update
@task = Task.find(params[:id])

respond_to do |format|
if @task.update_attributes(params[:task])
flash[:notice] = 'Task was successfully updated.'
format.html { redirect_to task_url(@task) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => @task.errors.to_xml }
end
end
end

# DELETE /tasks/1
# DELETE /tasks/1.xml
def destroy
@task = Task.find(params[:id])
@task.destroy

respond_to do |format|
format.html { redirect_to tasks_url }
format.xml { head :ok }
end
end
end

Monday, March 05, 2007

sudo: port: command not found

export PATH=$PATH:/opt/local/bin
export MANPATH=$MANPATH:/opt/local/share/man
export INFOPATH=$INFOPATH:/opt/local/share/info

Included the above lines in .bash_profile (my mac is using bash shell) and voila a nagging problem sudo: port: command not found is gone!!!

sudo port -d selfupdate

ran successfully. Now I was able to install FreeImage by running:
sudo port install freeimage

Thursday, March 01, 2007

LoadError: no such file to load — selenium

LoadError: no such file to load — selenium. This kind of error message can happen if you have installed anything as a gem but you have not specified require "rubygems" as the first statement in your program.

Wednesday, February 28, 2007

LoadError: no such file to load — flexmock

If you get this error, it means you need the statement: require 'rubygems' as the first line in your program.

Monday, February 05, 2007

Subversion 1.4.3 upgrade

Installed the latest version of Subversion. I had the older version 1.3, it looks like it installed successfully. svn --version shows the version as 1.4.3 and the files which were already in svn is still there.

Sunday, February 04, 2007

Spam Prevention using the Obfuscator Widget for Mac OS

This plugin obfuscates your email so that spambots cannot recognize the email that you post on your web page.

Testing... my email is : bparanj@gmail.com

CSS Tweak - Nice Widget for Mac OS to optimize CSS

CSS Tweak! widget is very useful plugin to optimize your CSS files. Just select the file you want to optimize from the Finder, hit F12 and drop it into the widget, select the options and the rest is done by the widget! Very cool.

Code to HTML Mac OS widget test - Download Code2HTML

#!/bin/sh
pid=$ ( ps -o pid, command | grep '\<script/server\>' | awk ' { print $1 } ' )
kill -9 $pid
ruby script/server

Code2HTML is a nifty little plugin that helps to convert the code to html. It solved my problem of posting code to the blog without messing up the characters. It is very quick and easy to convert the code to html.

Tuesday, January 23, 2007

Colorizing Autotest

1. install turn and facets
2. require 'turn' in environment.rb in the Rails project.

Step 2 must be done for each project that needs the colorizing of the autotest window. Another way to do this is shown in one of the topfunky's videos.

Friday, January 19, 2007

The new :& syntax in Ruby

The advantage of the new syntax is that it allows passing in a proc object, which is powerful.

I am surprised how the presenter in the No Fluff Just Stuff thought its main purpose was to make the code concise!