Tuesday, February 26, 2008

The way to have global constants in rails application

I don't know if there is a better or formal way to keep global constants for rails application. If I want to the global constants to be used only by controllers and views, the best way is to declared them in application helper. If active record is also to use them, I have to put the definitions in environment.rb. Like the following:

# Global constant for this application
# I define an array here
SOME_GLOBAL_INSTANT = [100, 300, 500, 800, 1000]

I googled by "rails global constants" but get no better solutions. Anyone knows this please tell me.

Another way to load config into controllers is to use YAML file, check out this blog post:

http://snippets.dzone.com/posts/show/287

3 easy steps to do Rails 2.0 pagination

Forget about the kind of awkward pagination of rails 1.x, now you need 3 easy steps to do Rails 2.0 pagination.

1. Install the pagination plugin:

ruby script/plugin install svn://errtheblog.com/svn/plugins/will_paginate

2. Type the following in your controller:

@products = Product.paginate(:page => params[:page], :per_page => 25)

3. Type the following in your view:

<%= will_paginate @products %>

The better thing comparing to rails 1.x pagination is that it is now easier to understand and remember. Isn't it more conventional?

Monday, February 25, 2008

A local Ruby script example with fileutils, open-uri, rmagick and mysql

##################################
# a code example for writing a ruby script to be running locally
# to do some regular local jobs such as:
# 1, download files or images from Internet
# 2, local file operations like mkdir, cp and remove
# 3, access or store data into local database like mysql
# 4, image resizing or cropping using image-magick
##################################
require 'open-uri'
require 'fileutils'
require 'RMagick'
require 'mysql'

# init local directories
FileUtils.mkdir_p "original/montreal"
FileUtils.mkdir_p "thumbnailed/montreal"

# init the database access
db = Mysql::new('127.0.0.1', 'root', '12345', 'test')

# init links to Internet
base_url = "http://farm1.static.flickr.com/"
image_urls = ['40/123180238_552597a079_b.jpg',
'146/390735501_54f0b2e826_b.jpg',
'50/131278273_4ce6400bfa_b.jpg']

# create a table to store image names
db.query("DROP TABLE IF EXISTS images")
db.query("CREATE TABLE images (name VARCHAR(64))")
image_urls.each do |image|
db.query("INSERT INTO images (name) VALUES ('#{image}')")
end

# download images from Internet
for i in 0..2
open("original/montreal/#{i}.jpg", 'wb').write(open("#{base_url}#{image_urls[i]}").read)
end

# resize and crop images
for i in 0..2
image = Magick::Image.read("original/montreal/#{i}.jpg").first
image.crop_resized!(150, 150, Magick::NorthGravity)
image.write("thumbnailed/montreal/#{i}.jpg")
end
References:

Ruby MySQL: http://www.tmtm.org/en/mysql/ruby/
RMagick: Making thumbnails with RMagick
FileUtils: http://www.ruby-doc.org/stdlib/libdoc/fileutils/rdoc/index.html
Ruby OpenURI: http://www.ruby-doc.org/core/classes/OpenURI.html

Basic flow to use rails file_column plugin

1. Create your table with a string field to store file name. For example:

create_table :products do |t|
t.string "name"
t.string "model"
t.string "image"
t.timestamps
end

2. Install file_column plugin:

script/plugin install http://opensvn.csie.org/rails_file_column/plugins/file_column/trunk

3. Install ImageMagick to your system and plugin RMagick

Visit http://rmagick.rubyforge.org/ for more detail

4. Put file_column description for model field into your model code. For example here, add to product.rb:

file_column :image, :magick => {
:versions => { "thumb" => "60x60", "medium" => "320x240"}
}

5. Generate controller and views for your model. I use rails 2.0 scaffold generator here:

script/generate scaffold product --skip-migration
add layout and authentication before_filter to product controller if needed
add _form.html.erb with form fields for new.html.erb and edit.html.erb to use
edit index.html.erb to show the list of products, such as <%= f.text_field :name %>

6. Show and upload image of product, edit in the _form.html.erb:

remove <%= f.text_field :image %>
add:
<% if !@product.id.nil? # in the case of edit %>
<%= image_tag url_for_file_column("product", "image", "medium") %>
<% end %>
<%= file_column_field "product", "image" %>

7. Add multipart to form tag in the edit and new files.

<% form_for(@product, :html => {:multipart => true}) do |f| %>

8. To show image in the list:

<% @product = product %>
<%= image_tag url_for_file_column("product", "image", "thumb") %>

Sunday, February 24, 2008

Tips to use scaffold generator of rails 2.0

There are big differences for the scaffold between rails 2.0 and rails rails 2.0 scaffold", like me, you can find a lot of good blogs or articles to learn about the new ways to use rails 2.0 scaffold. Anyhow, I would like to add some basic tips here, which I used a lot.

Number one tip is to use the help from rails itself:
script/generate scaffold -h

In rails 1.x, I created model and table in db firstly then do the scaffold, now the generator can do the model and table in the same time. The way to keep your old habit is to use:
> script/generate scaffold category(or other model name) --skip-migration

In the views, I need add the _form.html.erb by myself.

The generator will also put a map.resources in your routes.rb. If I want to add new actions such as batch_new and batch_create into this categories_controller. Config the routes.rb:
map.resources :categories,
:collection => {:batch_new => :get, :batch_create => :post}

Wednesday, February 20, 2008

Rails 2.0 tip: Create a new application with MySQL support

In rails < 2.0, when I create a rails new application by the rails command, the configuration of database.yml supports MySQL by default. While in rails 2.0, it will generate default configuration database.yml for Sqlite3. To make it default as MySQL, run with -d mysql.
rails -d mysql your_application_name

Thursday, February 14, 2008

Install and config rails plugin restful_authentication

Ruby on rails plugin Restful_authentication is a basic plugin useful for most of rails applications. It is very easy to intall and config it:
script/plugin source http://svn.techno-weenie.net/projects/plugins
script/plugin install restful_authentication
script/generate authenticated user sessions
rake db:migrate

Check the code in your routes.rb which is automatically added by the generation
map.resources :users
map.resource :session

Add more route mapping if your want
map.signup '/signup', :controller => 'users', :action => 'new'
map.login '/login', :controller => 'sessions', :action => 'new'
map.logout '/logout', :controller => 'sessions', :action => 'destroy'

Visit http://localhost:3000/users/new or http://localhost:3000/signup

Then to make it work with Comatose, add comatose config to evironment.rb of your app:
Comatose.configure do |config|
# Includes AuthenticationSystem in the ComatoseAdminController
config.admin_includes << :authenticated_system

# Calls :login_required as a before_filter
config.admin_authorization = :login_required
end

Thursday, February 7, 2008

Some problems of the installation of Rails Comatose Plugin

Comatose is a very handy content management ruby on rails plugin. Here I am listing some problems that I encountered when I get Comatose running correctly. Most of them can be easily fixed by googling. It is just a quick summary just in case you get the same kinds of problems or errors as I did.

To install it:
script/plugin install http://comatose-plugin.googlecode.com/svn/trunk/comatose
script/generate comatose_migration
rake db:migrate
# add to your routes.rb:
map.comatose_admin
map.comatose_root 'pages'
script/server
# visit content admin http://localhost:3000/comatose_admin
# after add a page of name My Page
# visit it at http://localhost:3000/pages/my-page

1. Do rake db migration, get a Mysql::Error: BLOB/TEXT column 'full_path' can't have a default value. To fix it, remove ":default => ''" from the definition of column 'full_path', in the migration file db/migrate/xxx_add_comatose_support.rb

2. To start your rails app, get an error `method_missing': undefined method `comatose_admin' for #. I got this routing error after I use Active Merchant plugin, can not figure out why. Add this to environment.rb to make Comatose plugin be loaded firstly:
config.plugins = [ :comatose, :all ]

3. Install necessary plugins
./script/plugin install acts_as_tree
./script/plugin install acts_as_list

4. To customize comatose admin view
rake comatose:admin:customize

This task will copy all of admin view rthml files to app/view/comatose_admin directory of your rails app. There is a new layout file comatose_admin.rhtml. Modify this layout file to customize your admin view.

Monday, February 4, 2008

Auto ssh login from Cygwin to linux server

I have a ssh2 client software installed before the installation of cygwin, but I never tried the auto login by public key successfully, one reason, I guess, is that my remote server doesn't have SSH2 server installed. Now that I am using cygwin, i install the openssh (not openssl) module from cygwin installation packages.

[cygwin:~/] ssh-keygen -t rsa (leave passphrase empty to make ssh-login easier)
[cygwin:~/] cd .ssh
[cygwin:~/] scp id_rsa.pub username@remote_host:.ssh/ (enter password this time)
[cygwin:~/] ssh username@remote_host (enter password this time)
[remote_host:~/] cd .ssh (create one if not existed)
[remote_host:~/] touch authorized_keys (create this file is not existed)
[remote_host:~/] cat id_rsa.pub >> authorized_keys
[remote_host:~/] rm -f id_rsa.pub
[remote_host:~/] chmod 600 authorized_keys
[remote_host:~/] cd ..
[remote_host:~/] chmod 700 .ssh
[remote_host:~/] exit
[cygwin:~/] ssh username@remote_host
[========== no password anymore, also for scp ===========]

Saturday, February 2, 2008

Run Ruby, Gems, Rails, MySQL and RMagick on Cygwin

Before using cygwin, I did not expect that the commands of rails do not work in cygwin. To make ruby, gems and rails to work, there are some additional tasks to do as following:

  • Add devel -> make + ruby + gcc + subversion modules from cygwin installation
  • Download gems tgz install package from Ruby Gems download home
  • tar xzvf rubygems-1.0.x.tgz
  • cd rubygems-1.0.x
  • unset RUBYOPT (before install gems, clear RUBYOPT=rubygems)
  • ruby setup.rb
  • gem install rails --include-dependencies
  • Download mysql source tar.gz file from MySQL download page
  • tar xzvf mysql-5.0.45.tar.gz
  • cd mysql-5.0.45
  • ./configure
  • make install ( or to do it faster, just make install under sub directories libmysql and include.
  • gem install mysql
  • Change the database server from localhost to 127.0.0.1 in the database.yml of your rails app
  • Install ImageMagick, libmagick-devel, XFree86-lib-compat, xorg-x11-devel, libbz2-devel module from cygwin installation file
  • gem install RMagick
  • ruby script/server. voila!

References:

Labnotes: Setting up Ruby + Gems on Cygwin
Softpedia: Install Rails on Windows with cygwin

Vim of Cygwin to Set default file format

If create a bash file under cygwin using vim, the default configuration of vim stores the bash file in the format of dos, therefore the bash file can not execute correctly.

To store the currently editting file in the format of unix:

:set fileformat (or ff)=unix

If I want to change the default file format of vim to unix, add this code into the .vimrc and .gvimrc file under my home directory:

set fileformats=unix,dos