To use helpers with email templates specify in the model the helpers you want to use.
class FooMailer < ActionMailer::Base  helper :Foo, :Application
For text fields one typically wants to allow some HTML tags, add support for link breaks and even auto link URL’s and emails.
This method which I got from this forum thread, Adding a line break … safely, does all of this and is a must add to my application_helper.rb.
def format_content(content) # allow only tags specified in tags options, likewise in attributes content = sanitize(content, :tags => %w(b strong i em img), :attributes => %w(src)) # add support for line breaks content = simple_format(content) # auto link URL's and emails content = auto_link(content, :all, :target => '_blank') return content end
Recently I tried running my RoR applications on Oracle.
I noticed that when I ran rake db:migrate it would hang. Specifically it would hang during the schema dump phase.
E:\work\sandbox>rake db:migrate --trace -v (in E:/work/sandbox) ** Invoke db:migrate (first_time) ** Invoke environment (first_time) ** Execute environment ** Execute db:migrate ** Invoke db:schema:dump (first_time) ** Invoke environment ** Execute db:schema:dump
I realized later that this was because the schema dump phase is very slow and the database I was using had many other tables from other applications. When I left it running it finally completed after 10 minutes.
You can see the slow progress of the schema dump phase by tailing schema.rb in the db directory.
E:\ruby>ruby ruby-oci8-1.0.3-mswin32.rb Copy OCI8.rb to e:/ruby/lib/ruby/site_ruby/1.8/DBD/OCI8 Copy oci8.rb to e:/ruby/lib/ruby/site_ruby/1.8 Copy oci8lib.so to e:/ruby/lib/ruby/site_ruby/1.8/i386-msvcrt OK? Enter Yes/No: Yes Copying OCI8.rb to e:/ruby/lib/ruby/site_ruby/1.8/DBD/OCI8 ... done Copying oci8.rb to e:/ruby/lib/ruby/site_ruby/1.8 ... done Copying oci8lib.so to e:/ruby/lib/ruby/site_ruby/1.8/i386-msvcrt ... done OK
You can test the driver by running a query using Ruby.
E:\>ruby -r oci8 -e "OCI8.new('foo','12345','sid').exec( 'SELECT * from users') do |r| puts r.join(' | ') ; end"
E:\ruby>install activerecord-oracle-adapter --source http://gems.rubyonrails.org
development: adapter: oracle database: sid username: foo password: 12345 timeout: 5000
This article is based on these articles.
Twitter has become the poster child of why not to use Ruby on Rails. Recently a friend of mine started a company and when I noticed he used PHP I asked why he didn’t use Rails. He responded “Twitter uses Rails and they keep going down. Facebook uses PHP. We’ll use PHP.”
There is an interesting interview w/ Twitter developer Alex Payne about the issues Twitter has had with Ruby on Rails.
The common wisdom in the Rails community at this time is that scaling Rails is a matter of cost: just throw more CPUs at it. The problem is that more instances of Rails (running as part of a Mongrel cluster, in our case) means more requests to your database. At this point in time there’s no facility in Rails to talk to more than one database at a time. The solutions to this are caching the hell out of everything and setting up multiple read-only slave databases..
All the convenience methods and syntactical sugar that makes Rails such a pleasure for coders ends up being absolutely punishing, performance-wise. Once you hit a certain threshold of
traffic, either you need to strip out all the costly neat stuff that Rails does for you (RJS, ActiveRecord, ActiveSupport, etc.) or move the slow parts of your application out of Rails, or both.It’s also worth mentioning that there shouldn’t be doubt in anybody’s mind at this point that Ruby itself is slow. It’s great that people are hard at work on faster implementations of the language, but right now, it’s tough. If you’re looking to deploy a big web application and you’re language-agnostic, realize that the same operation in Ruby will take less time in Python. All of us working on Twitter are big Ruby fans, but I think it’s worth being frank that this isn’t one of those relativistic language issues. Ruby is slow.
In April 2007, former Chief Architect Blaine Cook made a presentation called Scaling Twitter. It’s a well done presentation, even if everything is black.
In May 2008 there were rumors that Twitter was abandoning Rails. SitePoints believes it is not a framework issue but rather an architectural issue that is causing Twitter’s problems.
There are many large sites that run Rails well and many smaller ones that do not. It seems like another case of the “leaky abstraction” where we have such a nice framework that we think we can abstract away issues like scaling but in the end when the site becomes big enough we have to look under the covers.
Ruby has been documented to have I/O issues and general performance issues. Like PHP before it looks like Ruby needs to mature more and deal better with scaling and I/O issues. I am confident though this will happen because of the tremendous momentum of Ruby on Rails. However I am keeping on eye on Django, especially now that Google has thrown its large hat into Django’s ring.
This post about Monit and Mongrel is based on this fantastic post, Monit makes Mongrel play nice!
Install Monit from source:
$ wget http://www.tildeslash.com/monit/dist/monit-4.10.1.tar.gz $ tar xvfz monit-4.10.1.tar.gz $ cd monit-4.10.1 $ ./configure -prefix=/usr (the default prefix is /usr/local) $ make $ make install
Configure Monit:
In the monit source you will find a sample monitrc which is completely commented out. You can then copy it to wherever you like and then edit it. Here is my monitrc.
# Start monit in the background (run as a daemon) and check services at # 1-minute intervals. set daemon 60 # Set logging. set logfile /tmp/monit.log # Set the list of mail servers for alert delivery. set mailserver localhost # Set alert recipients. set alert foo@example.com # receive all alerts # Start Monit's embedded web server. set httpd port 2812 and allow admin:monit # require user 'admin' with password 'monit' # Mongrel - Development # Check that Mongrel is running and that it responds to HTTP # requests. Check its resource usage such as cpu and memory. If the # process is not running, monit will restart it by default. In case # the service was restarted very often and the problem remains, it is # possible to disable monitoring using the TIMEOUT statement. check process mongrel-dev with pidfile /rails/log/mongrel.pid start program = "/usr/bin/mongrel_rails start -d -c /rails -p 3000 -P /rails/log/mongrel.pid" stop program = "/usr/bin/mongrel_rails stop -P /rails/log/mongrel.pid" if cpu > 50% for 2 cycles then alert if cpu > 80% for 5 cycles then restart if totalmem > 60.0 MB for 5 cycles then restart if loadavg(5min) greater than 10 for 8 cycles then restart if failed port 3000 protocol http with timeout 15 seconds for 2 cycles then restart if 3 restarts within 5 cycles then timeout group mongrel-dev
After you are done configuring monitrc copy it to /etc.
$ sudo cp monitrc /etc
To test the configuration:
$ sudo monit -t
Run Monit:
To start monit:
$ sudo monit
To restart monit:
$ sudo monit reload
To stop monit:
$ sudo monit quit
To see monit’s log (assuming you are using my configuration):
$ tail -f /tmp/monit.log
Learn More:
Today I took the plunge and installed Rails 2.0.2. Notes on the Rails 2.0 release can be found here.
Here are the steps I took.
gem update --system
gem install rails -v 2.0.2
gem install mysql
rails prayer -d mysql
cd prayer
ruby script/plugin install http://svn.techno-weenie.net/projects/plugins/restful_authentication/
ruby script/generate scaffold Prayer title:string body:text
--include-activation
flag is to create the mailers for activation and signup notification.ruby script/generate authenticated user sessions --include-activation
rake db:migrate
app/models/user_mailer.rb
, replacing the place holders with constants which you can configure with different values for different environments using config/environments/development.rb
, config/environments/production.rb
.ruby script/generate scaffold Role rolename:string
ruby script/generate model Permission
Much of this post is based on this excellent post, Restful Authentication with all the bells and whistles. At this point I did not continue with much of the tutorial, especially with parts like password forgotten, separate account controller, etc.
When I run rake db:migrate I get this error at the end.
Error in my_thread_global_end(): 1 threads didn't exit
I pinned it down to this code in one of my migration files.
# create admin user user = User.new user.login = 'admin' user.password = 'password' user.save(false)
If I don’t run user.save(false) I don’t get the error. I am not sure why, the user does get saved properly to the database.
I saw this post on the MySQL forums that seemed to indicate it was an issue with libmySQL.dll. So I upgraded my MySQL instance from 5.0.27 to 5.0.51a. Of course this did not go smoothly, I got this error when trying to reconfigure the MySQL server instance “MySQL service could not be started error 0”. Fortunately another post on the MySQL forums, Could not start service : Error 2003, solved this problem for me. I just had to remove the following files from the mysql/data directory.
Unfortunately when I then did a rake db:migrate I saw this error.
Mysql::Error: Table 'prayer.schema_info' doesn't exist: SELECT version FROM schema_info
After deleting and recreating the database I was finally able to run rake db:migrate. Unfortunately I still got the same error that inspired this post.
Googling some more I saw a MySQL bug report, MySQL Bugs: #25621: Error in my_thread_global_end(): 1 threads didn’t exit. Apparently this is a client side issue and I think I can safely ignore it though it is quite annoying.
Strictly speaking, this is not MySQL bug. This is a client bug – a client application (PHP, probably) linked with libmysqlclient calls my_thread_init() but does not call my_thread_end() as appropriate (doesn’t call at all or calls too late). MySQL client library detects this and issues a warning.
On the other hand, we can just remove the check and let buggy applications to fail some other way. Not calling my_thread_end() is a guaranteed memory leak. Calling it too late could easily crash the application.
I tried to update the restful_authentication plugin by doing this.
$ ruby script/plugin update restful_authentication
Unfortunately it didn’t do anything.
I know I don’t have the latest version because in another project I pulled down the latest restful_authentication code and it was different.
To get around this I forced an install with the latest code.
$ ruby script/plugin install -x \ http://svn.techno-weenie.net/projects/plugins/restful_authentication/
Fortunately I received an answer about this on the rails mailing list. Apparently update only works if the plugin is in svn:externals. To do this you would install it with the -x flag (see list of flags by doing ruby script/plugin install -h’).
However if you try this with the restful_authentication plugin you’ll see this.
$ ruby script/plugin install -f \ http://svn.techno-weenie.net/projects/plugins/restful_authentication/ Cannot install using externals because this project is not under subversion.
Previously I talked about configuring a production Ruby on Rails applications using a Mongrel cluster with an Apache front end / load balancer. Now though a new Apache module was released called mod_rails which obviates the need for a Mongrel cluster. Seems promising, both for simplicity of installation and performance.