betweenGo

Tag: Ruby on Rails

My First Rails 2.0 Application w/ Restful Authentication

by on Apr.07, 2008, under Ruby on Rails

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.

  1. Upgrade Ruby Gems to the latest version (in this case 1.0.1).
    gem update --system
  2. Install Ruby on Rails 2.0.2.
    gem install rails -v 2.0.2
  3. Install MySQL gem (as of March 5, 2008, it is version 2.7.3) and add MySQL executable to path.
    gem install mysql
  4. Create prayer application.
    rails prayer -d mysql
  5. Install Restful Authentication plugin.
    cd prayer
    ruby script/plugin install http://svn.techno-weenie.net/projects/plugins/restful_authentication/
  6. Create scaffold for prayer model.
    ruby script/generate scaffold Prayer title:string body:text

    The first thing I noticed different about Rails 2.0 is that the scaffold now also generates the model and data migration file with title and body as columns in the prayer table. Also the format of the data migration file is slightly more compact.
  7. Create user model with authentication. The --include-activation flag is to create the mailers for activation and signup notification.
    ruby script/generate authenticated user sessions --include-activation
  8. Configure config/database.yml and then create prayer and user tables in DB.
    rake db:migrate
  9. Configure SMTP settings.
  10. Modify 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.
  11. Modify user_observer.rb to incorporate the reset and forgotten password features.
  12. Create scaffold for role model. Add an admin user.
    ruby script/generate scaffold Role rolename:string
  13. Create permission model. Modify role and permission models to know about each other.
    ruby script/generate model Permission
  14. Modify user model to use permissions.

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.

Share
Leave a Comment : more...

‘Error in my_thread_global_end()’ when running rake db:migrate

by on Apr.03, 2008, under MySQL, Ruby on Rails

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.

  • ib_logfile0
  • ib_logfile1
  • ibdata1

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.

Share
2 Comments :, more...

Problem updating restful_authentication plugin

by on Apr.02, 2008, under Ruby on Rails

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.
Share
Leave a Comment : more...

mod_rails

by on Apr.01, 2008, under HTTP Server, Ruby on Rails

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.

Share
Leave a Comment : more...

Installing Apache 2.2 with mod_rewrite and mod_proxy_balancer

by on Mar.31, 2008, under HTTP Server, Ruby on Rails

As mentioned in my post, Configuring Apache to work with a Mongrel Cluster, you need an Apache installation with mod_rewrite and mod_proxy_balancer. Unfortunately on the Red Hat installation I was using the default installation is Apache 2.0 which does not have mod_proxy_balancer. When I tried to upgrade it using up2date I got some errors that seemed to indicate this install was not properly registered. I then tried using the Apache 2.2 install done by the tech guy but this install did not have the modules I needed.

Therefore it was time for me to do the install by myself. Fortunately it was not hard with the help of this article, Building Apache 2.2 plus the manual.

Here is what I did.

$ wget http://apache.mirror99.com/httpd/httpd-2.2.8.tar.gz
$ tar xvfz httpd-2.2.8.tar.gz
$ cd httpd-2.2.8
$ ./configure --enable-rewrite=shared --enable-proxy=shared \
    --enable-proxy_balancer=shared --enable-proxy_http=shared
$ make
$ sudo make install
$ sudo /usr/local/apache2/bin/apachectl start
Share
3 Comments : more...

Configuring Apache to work with a Mongrel Cluster

by on Mar.31, 2008, under HTTP Server, Ruby on Rails

Previously I wrote about Configuring Capistrano and Mongrel. Now we are going to configure Apache to work with the Mongrel cluster.

For this article I used the chapter Setting Up A Development Environment in Agile Web Development with Rails, version 2.0, plus this article.

Capistrano working together with Mongrel allows you to deploy and restart Mongrel clusters quite nicely.

Configure Apache proxy balancer

Apache has a mod_proxy_balancer module which must be enabled. Once this is done you can add the following to the end of conf/httpd.conf or if you are on Red Hat Linux you can put the proxy balancing section in /etc/httpd/conf.d/myapp.proxy_cluster.conf and the virtual host section in /etc/httpd/conf.d/myapp.conf.

<Proxy balancer://mongrel_cluster>
  BalancerMember http://127.0.0.1:8000
  BalancerMember http://127.0.0.1:8001
  BalancerMember http://127.0.0.1:8002
</Proxy>

<VirtualHost *:80>
  Include conf/myapp.common (or Include conf.d/myapp.common)
  ErrorLog logs/myapp_errors_log
  CustomLog logs/myapp_log combined
</VirtualHost>

Configure Apache Virtual Host

Next you configure the virtual host that represents the Ruby on Rails application in the custom file conf/myapp.common or if you are on Red Hat Linux in /etc/httpd/conf.d/myapp.common.

ServerName myapp.com
DocumentRoot /usr/local/rails/myapp/current/public

<Directory "/usr/local/rails/myapp/current/public">
  Options FollowSymLinks
  AllowOverride None
  Order allow,deny
  Allow from all
</Directory>

RewriteEngine On

# Uncomment for rewrite debugging
#RewriteLog logs/myapp_rewrite_log
#RewriteLogLevel 9 

# Check for maintenance file and redirect all requests
RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
RewriteCond %{SCRIPT_FILENAME} !maintenance.html
RewriteRule ^.*$ /system/maintenance.html [L]

# Rewrite index to check for static
RewriteRule ^/$ /index.html [QSA] 

# Rewrite to check for Rails cached page
RewriteRule ^([^.]+)$ $1.html [QSA]

# Redirect all non-static requests to cluster
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ balancer://mongrel_cluster%{REQUEST_URI} [P,QSA,L]

Restart Apache

$ sudo /usr/local/apache2/bin/httpd -k restart

or

$ sudo /etc/init.d/httpd restart
Share
1 Comment : more...

Difference between require and require_dependency

by on Mar.29, 2008, under Ruby on Rails

I was wondering what the difference was between require and require_dependency.

According to this post in comp.lang.ruby the difference is not significant but interesting. Looks like I’ll be using require_dependency from now on.

require loads a file (shared object or ruby source) once from the load path.

require_dependency isn’t a ruby core feature, it’s part of rails. It remembers the given file and loads it on each new server request (like load “path/file.rb” does), if development mode is enabled:

http://wiki.rubyonrails.com/rails/pages/RequireDependency


Florian Frank

Share
Leave a Comment : more...

Configuring Capistrano and Mongrel

by on Mar.28, 2008, under Ruby on Rails, Subversion

For this article I used the chapter Setting Up A Development Environment in Agile Web Development with Rails, version 2.0, plus these two articles.

Capistrano working together with Mongrel allows you to deploy and restart Mongrel clusters quite nicely.

Configure Mongrel Cluster

First you need to configure a Mongrel cluster. Here is an example that creates three Mongrel instances starting at port 8000, listening on the local interface, 127.0.0.1.

$  mongrel_rails cluster::configure -N 3 -p 8000 -e production -a 127.0.0.1 \
   -c /usr/local/rails/production/current \
   -C /usr/local/rail/production/current/config/mongrel_cluster.yml

Here is how the created file looks like.

---
cwd: /usr/local/rails/production/current
log_file: log/mongrel.log
port: "8000"
environment: production
address: 127.0.0.1
pid_file: tmp/pids/mongrel.pid
servers: 3

Note that for testing purposes you should comment out the address line.

#address: 127.0.0.1

We specified listening only on the local interface for security purposes but for testing the cluster we need to access it directly via its remote IP address.

Setup Capistrano

Next you create a stub Capfile and config/deploy.rb.

$ capify .

Now you can get a list of all the tasks that are available and there quite a few.

$ cap -T

Next modify config/deploy.rb like in this example.

require 'mongrel_cluster/recipes'

set :application, "foobook"
set :repository, "http://example.com/svn/foo/trunk/foobook"

role :web, "192.168.3.17"
role :app, "192.168.3.17"
role :db,  "192.168.3.117", :primary => true

set :deploy_to, "/usr/local/rails/production"
set :mongrel_conf, "#{current_path}/config/mongrel_cluster.yml"
set :svn_user, "fkim"
set :svn_password, "fkim"
#set :user, "root"            # defaults to the currently logged in user
set :scm, :subversion         # defaults to :subversion
set :svn, "/usr/bin/svn"      # defaults to searching the PATH

Deploy using Capistrano

Now run setup which will create the directories remotely.

$ cap deploy:setup

Check dependencies.

$ cap -q deploy:check

Deploy for the first time.

$ cap deploy:cold

Everytime after you can deploy like this.

$ cap deploy

Starting and Stopping Mongrel using Capistrano

If you want to just start the mongrel cluster.

$ cap mongrel:cluster:start

If you want to just stop the mongrel cluster.

$ cap mongrel:cluster:stop

And that’s it.

Not that bad at all. Starting and stopping mongrel was the biggest issue for me. I realized that I did not need to create the spin script as suggested in the Using Capistrano with Rails article. If the mongrel configuration is correct then Capistrano will correctly start and stop it and you can use the above cap commands to test it.

Share
3 Comments :, more...

Installing Ruby on Rails on Red Hat Enterprise Linux 4

by on Mar.28, 2008, under Ruby on Rails

This post is based on instructions from these articles.

Determine what Ruby RPMs are installed:

$ rpm -qa | egrep '(ruby)|(irb)'
ruby-libs-1.8.1-7.EL4.2

Uninstall Ruby RPMs:

$ sudo rpm -e ruby-libs-1.8.1-7.EL4.2

Install Ruby from source:

$ wget ftp://ftp.ruby-lang.org/pub/ruby/ruby-1.8.6-p114.tar.gz$ tar xvfz ruby-1.8.6-p114.tar.gz
$ cd ruby-1.8.6-p114
$ ./configure --prefix=/usr (the default prefix is /usr/local)
$ make
$ make test
$ sudo make intall

Install Ruby Gems:

$ wget http://rubyforge.org/frs/download.php/29548/rubygems-1.0.1.tgz
$ tar xvfz rubygems-1.0.1.tgz
$ cd rubygems-1.0.1
$ sudo ruby setup.rb

Install Rails:

$ sudo gem update
$ sudo gem update --system
$ sudo rm `gem env gempath`/source_cache
$ rm -f ~/.gem/source_cache
$ sudo gem update
$ sudo gem install rails -v 1.1.6
$ sudo gem install rails -v 1.2.6
$ sudo gem install rails (if you want the latest version, 2.0.2)

Install Capistrano:

$ sudo gem install capistrano

Install Mongrel:

$ sudo gem install mongrel
$ sudo gem install mongrel_cluster

Install Memcache Client:

$ sudo gem install memcache-client

Share
2 Comments : more...

You Used Ruby to Write WHAT?!

by on Mar.13, 2008, under Ruby on Rails

The brilliant Zed Shaw, author of Mongrel and many other open source projects, wrote a fantastic article called You Used Ruby to Write WHAT?! which is a part of series of acticles called You Used THAT Programming Language to Write WHAT?!

Some interesting quotes from the Ruby article.

Web programming, sometimes. Ruby on Rails (RoR) is potentially a huge cost-saving framework for developing Web applications. Complex applications are measured in thousands of lines of code rather than 10- or 100-thousands of lines.

The caveat on Ruby for Web programming is that Rails is better suited for building Web applications. I’ve seen many projects attempt to create a WebDAV server or a content management system (CMS) with Rails and fail miserably. While you can do a CMS in Rails, there are much more efficient technologies for the task, such as Drupal and Django. (In fact, I’d say if you’re looking at a Java Portal development effort, you should evaluate Drupal and Django for the task instead.)

Large data crunching. It’s sad to say, but Ruby (all versions worth using in production, and even Ruby 1.9) suffer from huge problems with large-scale garbage collection, I/O processing and thread operations. Ask anyone running a Rails application that accepts large file uploads; they’ll tell you it chews their CPU just to process the MIME boundaries in the request body. Ruby has had (and still has) frequent bugs and misfeatures in its garbage collector (GC) implementation that makes handling large chunks of data difficult. Yes, you can do it; and yes, being clever helps; but why bother, when you can just use a language without such problems?

Image manipulation. I don’t really think many languages are great at image manipulation, but Ruby is particularly bad at it. The primary libraries available are based on Image Magick, which is slow, bloated and takes forever to install on many systems. Ruby talks to Image Magick through RMagick, which suffers from memory leaks, spawns external processes silently for many operations and is difficult to install (unless your computer is nearly exactly the same as the author’s). Other libraries are no better. Either they don’t support many operations, or they also require a myriad of dependencies, build tools and other requirements just to do limited image manipulation.

Server protocols. Ruby’s problems with I/O processing means that writing truly scalable servers is a waste of time. Most of the people I know doing server work in Ruby eventually give up and either use a mix of Ruby and C or they switch to another language entirely.

With Ruby’s garbage collection problems, you’ll have issues with long-running processes, especially if they have to process large data streams and you’re not careful about how you deal with them. With Ruby’s Threads you’ll find many problems when you try to scale your application beyond the 1,024 open files Ruby can handle. Ruby’s Thread contains several technical flaws that make it unsuitable for really huge-scale operations. Ruby can handle large network traffic, but it takes more careful planning and programming than with many other languages.

Enterprise deployments. The “enterprise” hates Ruby, and this is mostly a social problem. The majority of corporate systems are based on either Java or C#, with no room for a rogue language like Ruby.

In fact, take a good hard look at many of the companies running large-scale systems. You’ll see Python at Google, PHP at Yahoo, Perl at Amazon, Java at eBay—but very little Ruby. This will change as Ruby on Rails becomes popular.

I discovered that most of the college students either were working with Ruby or planned to adopt it. Either that, or they used Java because their university required it. Very few were interested in languages like Python, Perl, Java or C, except when it was required or could get them a job. This has probably been the most overlooked “feature” of Ruby by most people advocating it: Young kids actually want to work for you if you build software in Ruby or Python, Erlang, Haskell or Lisp.

Share
1 Comment : more...

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!