Archive for the 'Ruby on Rails' Category

Using RMagick to create cool photos

Wednesday, June 18th, 2008

Having something like this

Wouldn't it be cool if you could creating something like this?

All in real-time, in your Ruby on Rails project, using RMagick.

Hold on because I'll show you how. (more…)

Temporarily disable Rails timestamp magic columns updates

Friday, April 18th, 2008

I recently faced a problem when I didn't want Rails' timestamp "magic" columns to be updated during update of records in database. I have a site where recently updated pages are displayed on front page, and I use updated_at timestamp to identify the most recently updated ones. However, the system also has a feature to reorder pages, where only the 'position' attribute is updated, and not the actual page content. The reorder operation can't be counted as a real update. However, any saves or update_attribute operations on a model fire up the magic columns update.

However, there's a simple way to permanently turn this feature off. Here's how I implemented it:

ActiveRecord::Base.record_timestamps = false #temporarily turn off magic column updates

@page.update_attribute(:position, pos)

ActiveRecord::Base.record_timestamps = true #turning updates back on

Rails mailer's receive and sendmail procmail "Service unavailable" problem

Wednesday, February 13th, 2008

I have migrated all my Ruby on Rails system from Fedora Core 6 to RedHat 4.5 recently, and everything was fine, except for that the feature of blogging by email was broken (got a phone call today about that).

I use standard sendmail/procmail integration feature to receive mail to a designated address,  and then pipe it into Rails Mailer's receive function.

So, it looks like that in my /etc/mail/virtusertable:

m@example.com        examplemobile

this way all email which is coming to m@example.com address will be forwarded to system user called examplemobile.

In order to process the mail further and pipe it into my Rails script, I have the following setup in my /etc/aliases file :

examplemobile: "|/usr/local/bin/ruby /var/www/html/examplesite/current/script/runner -e production 'Mailman.receive STDIN.read'"

This setup worked perfectly on Fedora, but broke under RedHat. What's the problem? I was getting the following errors in my maillog:

Feb 13 11:45:33 appserv1 sendmail[32000]: m1D2jXJw032000: from=<xxxxxx@c.vodafone.ne.jp>, size=397, class=0, nrcpts=1, msgid=<20080213114719020972.1b6f@0016E68C4270>, proto=SMTP, daemon=MTA, relay=mmrts035p01c.softbank.ne.jp [123.108.236.87]
Feb 13 11:45:33 appserv1 smrsh: uid 8: attempt to use "ruby /var/www/html/examplesite/current/script/runner -e production 'Mailman.receive STDIN.read'" (stat failed)
Feb 13 11:45:33 appserv1 sendmail[32001]: m1D2jXJw032000: to="|/usr/local/bin/ruby /var/www/html/examplesite/current/script/runner -e production 'Mailman.receive STDIN.read'", ctladdr=<m@examplesite.com> (8/0), delay=00:00:00, xdelay=00:00:00, mailer=prog, pri=30623, dsn=5.0.0, stat=Service unavailable

The problem turned out to be in sendmail setup under RedHat was more secure than the one I had in Fedora. Specifically, this has to do with smrsh (or Sendmail Restricted Shell) thingy. More info about it here. Basically, sendmail only allows piping to programs which (or aliases to them) are present in /etc/smrsh directory.

Since I only use ruby to pipe to, I have added a symbolic link to it inside the /etc/smrsh directory:

[mike@appserv1 smrsh]$ pwd
/etc/smrsh
[mike@appserv1 smrsh]$ ls -l
lrwxrwxrwx  1 root root 19 Feb 13 11:50 ruby -> /usr/local/bin/ruby

Everything works as it should now, and our mobile-blogging users are supposedly happy again :)

Moving to Capistrano 2 deployment, at last

Tuesday, February 5th, 2008

Though I have moved my latest Rails apps to Rails 2.0, I've been pretty slow moving my deployment recipes from older Capistrano 1.x to the new Capistrano 2.x series.

Capistrano ultimately lacks any documentation which can even remotely be called "complete" or "easy to understand", so it definitely takes much more time that it actually should take, to understand how the bloody thing works. Sure, this of course includes annoying trips into Cap's source code and stuff like that, which is not a great time saver.. End of rant.

Anyways, you can be a lazy folk like myself lately, and just deploy your Rails 2.x compatible app using old Capistrano 1.2 recipes:

cap _1.2.0_ deploy

But the time will come and you'll want to ultimately move the stuff to the latest and greatest. And actually, it's pretty easy to do, _once_ you got the idea what needs to be done.

First, you need to capify your application, using

capify .

command in the top level of your application.

Next, you can replace contents of your old deploy.rb file with the following (or modified the following).

set :application, "your_application"

set :repository, "https://your-repository.com/svn/#{application}/trunk"
set :deploy_to, "/var/www/html/#{application}"

set :mongrel_config, "#{current_path}/config/mongrel_cluster.yml"
set :runner, "mike" #the default user is 'app'
set :deploy_via, :export
set :deploy_via, :remote_cache

set :keep_releases, "3"

role :web, "appserv1"
role :app, "appserv1"
role :db,  "dbserv1", :primary => true

namespace :deploy do

desc "Create symlinks for shared image upload directories"
task :after_update_code do
%w{gallery_items attachments image}.each do |share|
run "rm -rf #{release_path}/public/#{share}"
run "mkdir -p #{shared_path}/system/#{share}"
run "ln -nfs #{shared_path}/system/#{share} #{release_path}/public/#{share}"
end
end

desc "Restarts the pack of mongrels"
task :restart, :roles => :app do
restart_mongrel_cluster
restart_apache
end

desc "Restarts apache web server"
task :restart_apache, :roles => :app do
sudo "/usr/sbin/apachectl graceful"
end

end

desc "Start the mongrels"
task :start_mongrel_cluster, :roles => :app do
sudo "mongrel_rails cluster::start -C #{mongrel_config}"
end

desc "Stop the mongrels"
task :stop_mongrel_cluster, :roles => :app do
sudo "mongrel_rails cluster::stop -C #{mongrel_config}"
end

desc "Restart the mongrels"
task :restart_mongrel_cluster, :roles => :app do
stop_mongrel_cluster
sudo "rm -rf #{current_path}/tmp/pids/mongrel.*.pid"
start_mongrel_cluster
end

This assumes you run your apps on mongrels cluster, and that you wish to restart your apache server after every deployment (somehow, just restarting mongrels just don't work for me sometimes). Also, I use different servers for application and database. Other than that, it should work for you as is.

But of course, don't really believe me, and look thru this config before messing up with your deployment stuff :)

Rails active_record_store & Segmentation fault

Wednesday, December 19th, 2007

Here's a quick tip if you're getting errors like this one in your Rails application:

/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/session/active_record_store.rb:84: [BUG] Segmentation fault

The most probable reason you're getting the Segmentation fault and your server crashes is because you're trying to store too much data in sessions table of your application (I assume you are using active_record_store as a session store).

The problem with "too much data" is that by default, the session table creation rake task created the following migration in Rails 1.x:

class AddSessions < ActiveRecord::Migration
def self.up
create_table :sessions do |t|
t.column :session_id, :string
t.column :data, :text
t.column :updated_at, :datetime
end
add_index :sessions, :session_id
end

def self.down
drop_table :sessions
end
end

Please note the data field defined as text. This means that it can only store up to 64Kb of data. And that also means that if you're trying to store more than 64Kb in your session.

In order to fix the problem, you just need to manually change the column type before you run migration which creates session store, or just create a new migration which changes parameters of the data column in existing sessions table:

Should look something like that (Rails 2 syntax):

class CreateSessions < ActiveRecord::Migration
def self.up
drop_table :sessions

create_table :sessions do |t|
t.string :session_id, :null => false
t.column :data, :binary, :limit => 10.megabyte
t.timestamps
end

add_index :sessions, :session_id
add_index :sessions, :updated_at
end

def self.down
drop_table :sessions
end
end

Empty your sessions table, restart your server and you're done. No more segmentation faults. Of course you shouldn't store that much data in a session in the first place, but well.. things happen. Now I'm off to fix my code which stores Megs of data in a session store ;)

Rails 2.0 is out so…

Friday, December 7th, 2007

..just kill me because I absolutely have no time to dig into it doh! For these lucky who do have time, follow here Somebody stop the planet and give me a couple of months of rest with just me and the computer (and the Internet, of course) :) 

Turn off / tune logger level in Rails

Friday, November 9th, 2007

If you haven't noticed already, Rails-based application's logs can grow up pretty fast with default settings even in production mode. I just have one system which generated about 500Megs of production.log in just about a month. This is not a very good situation when you're on a shared host with limited hard disk space. So unless you are totally anal about what's going when on your production server (and well.. I don't know why you should be, since stuff is supposed to be at least partially stable when you actually deploy it) - you might want to limit logging, or eliminate it completely. Here's how.By default, logging level in production mode is set to :info, meaning every request will be logged, and that's not your Apache log. A single entry is something like that:

Processing FrontController#news (for 124.110.11.17 at 2007-11-09 17:55:11) [GET]  Session ID: f14f25c56d59f278194146955357c198  Parameters: {"action"=>"news", "id"=>"249", "controller"=>"front"}Cookie set: visitor_id=177; path=/; expires=Sat, 08 Nov 2008 14:55:11 GMTRendering  within layouts/kyoroman/frontRendering front/newsCompleted in 0.56727 (1 reqs/sec) | Rendering: 0.29647 (52%) | DB: 0.00000 (0%) | 200 OK [http://kyo-roman.com/news/249]  

Pretty long for a single request huh? And do you really really need this info in your logs?If not, just open your config/production.rb file and add the following line:

 config.log_level = :error  

This way only errors will be logged. You can use :fatal instead of :error and have even fewer stuff being logged.But still, even with :fatal settings, SOME stuff will be logged, and this stuff are really fatal dumps like:

ActionController::UnknownAction (No action responded to unknown_request):    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.2/lib/action_controller/filters.rb:632:in `call_filter'    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.2/lib/action_controller/filters.rb:638:in `call_filter'    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.2/lib/action_controller/filters.rb:438:in `call'    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.2/lib/action_controller/filters.rb:637:in `call_filter'    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.2/lib/action_controller/filters.rb:638:in `call_filter'  

…………………. many many lines ……………… 

So you might want to just disable the whole logging totally. In a hasta-la-vista-baby approach. In order to do that, just add the following 2 lines to the end of your environment.rb file:

ActiveRecord::Base.logger = nil

ActionController::Base.logger = nil 

 

 And that's it. You'll get zero-sized logs. Just remember - ALL logs will be empty, development, production and testing :)  Now.. I think there might be a better way to control logging, so if anyone knows a better way please share it in the comments. 

Rails and readline problems on Mac OS X

Friday, October 19th, 2007

If you build Ruby on Mac OS X yourself, you may face the following problem once you have downloaded the language's source from ruby-lang.org, compiled/installed it and tried to run your Rails app:

 mike$ script/console

Loading development environment.

dyld: NSLinkModule() error

dyld: Symbol not found: _rl_filename_completion_function

  Referenced from: /usr/local/lib/ruby/1.8/i686-darwin9.0.0b5/readline.bundle

  Expected in: flat namespace

 

Trace/BPT trap 

 

 In order to fix the problem, you need to re-build readline from the source and then rebuild Ruby, linking it to the new readline's installation dir. Here's how you do it:

wget ftp://ftp.gnu.org/gnu/readline/readline-5.1.tar.gz 

tar -xzf readline-5.1.tar.gz

cd readline-5.1

./configure –prefix=/usr/local && make && sudo make install

 

and then rebuild Ruby (you do it in your Ruby source directory of course)

make distclean && configure –with-readline-dir=/usr/local && make && make install   

Once done, everything should be back on track. 

New portal goes online

Tuesday, October 2nd, 2007

Being in development (mostly contents part, not the system itself) for a several months, a kimono-company portal which uses the multi-site system I have developed, have finally went live today :)

The Kyo-roman portal is a portal system for a company which sells kimonos here in Japan - the headquarters and filials (and that's 17 of them!) each got own web-site, with blog and news/events periodicals, centralized articles approval solution and other perks like visual editor and video uploads. Latest news from filial sites are all gathered on the top page of the headquarters' site (hey, it's a portal site, after all :).

Currently, sites of company's filials are pretty minimalistic, but hopefully that will change in the future (it's up to users to add new content from now on).

The system uses Ruby on Rails as development system (specifically, version early version of my Rails-based multi-site system) and is deployed on CentOS-based hosting, Apache 2 + Mongrel cluster.

Well I know this might sound pretty boring (bah.. ANOTHER system online, so what?), but this is actually the first large-scale deployment of the system I've been working on for over a year, so well.. this is kinda exciting for me :)

One more Rails project online

Thursday, September 20th, 2007

I have another project went live.

RightViewPro is a site for baseball fans, selling some pretty interesting baseball systems. The site is written completely in Rails, features rich admin interface, fully customizable thru admin panel, and features online shop with physical and downloadable products.

Cheers goes to WindUp Design team with whom I was working on the project.