Newer posts are loading.
You are at the newest post.
Click here to check if anything new just came in.

October 03 2011

20:22

How to Use Omniauth to Authenticate your Users

I hate signing up for websites. I’ve already signed up for so many, using different usernames, that going back to one of them and trying to remember my credentials is sometimes impossible. These days, most sites have begun offering alternative ways to sign up, by allowing you to use your Facebook, Twitter or even your Google account. Creating such an integration sometimes feels like a long and arduous task. But fear not, Omniauth is here to help.

Omniauth allows you to easily integrate more than sixty authentication providers, including Facebook, Google, Twitter and GitHub. In this tutorial, I’m going to explain how to integrate these authentication providers into your app.


Step 1: Preparing your Application

Let’s create a new Rails application and add the necessary gems. I’m going to assume you’ve already installed Ruby and Ruby on Rails 3.1 using RubyGems.

rails new omniauth-tutorial

Now open your Gemfile and reference the omniauth gem.

gem 'omniauth'

Next, per usual, run the bundle install command to install the gem.


Step 2: Creating a Provider

In order to add a provider to Omniauth, you will need to sign up as a developer on the provider’s site. Once you’ve signed up, you’ll be given two strings (sort of like a username and a password), that needs to be passed on to Omniauth. If you’re using an OpenID provider, then all you need is the OpenID URL.

If you want to use Facebook authentication, head over to developers.facebook.com/apps and click on “Create New App”.

Facebook New App

Fill in all necessary information, and once finished, copy your App’s ID and Secret.

Facebook Secret

Configuring Twitter is a bit more complicated on a development machine, since they don’t allow you to use “localhost” as a domain for callbacks. Configuring your development environment for this kind of thing is outside of the scope of this tutorial, however, I recommend you use Pow if you’re on a Mac.


Step 3: Add your Providers to the App

Create a new file under config/initializers called omniauth.rb. We’re going to configure our authentication providers through this file.

Paste the following code into the file we created earlier:

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :facebook, YOUR_APP_ID, YOUR_APP_SECRET
end

This is honestly all the configuration you need to get this going. The rest is taken care of by Omniauth, as we’re going to find in the next step.


Step 4: Creating the Login Page

Let’s create our sessions controller. Run the following code in your terminal to create a new sessions controller, and the new, create, and failure actions.

rails generate controller sessions new create failure

Next, open your config/routes.rb file and add this:

get   '/login', :to => 'sessions#new', :as => :login
match '/auth/:provider/callback', :to => 'sessions#create'
match '/auth/failure', :to => 'sessions#failure'

Let’s break this down:

  • The first line is used to create a simple login form where the user will see a simple “Connect with Facebook” link.
  • The second line is to catch the provider’s callback. After a user authorizes your app, the provider redirects the user to this url, so we can make use of their data.
  • The last one will be used when there’s a problem, or if the user didn’t authorize our application.

Make sure you delete the routes that were created automatically when you ran the rails generate command. They aren’t necessary for our little project.

Open your app/controllers/sessions_controller.rb file and write the create method, like so:

def create
  auth_hash = request.env['omniauth.auth']

  render :text => auth_hash.inspect
end

This is used to make sure everything is working. Point your browser to localhost:3000/auth/facebook and you’ll be redirected to Facebook so you can authorize your app (pretty cool huh?). Authorize it, and you will be redirected back to your app and see a hash with some information. In between will be your name, your Facebook user id, and your email, among other things.


Step 5: Creating the User Model

The next step is to create a user model so users may sign up using their Facebook accounts. In the Rails console (rails console), create the new model.

rails generate model User name:string email:string

For now, our user model will only have a name and an email. With that out of the way, we need a way to recognize the user the next time they log in. Keep in mind that we don’t have any fields on our user’s model for this purpose.

The idea behind an application like the one we are trying to build is that a user can choose between using Facebook or Twitter (or any other provider) to sign up, so we need another model to store that information. Let’s create it:

rails generate model Authorization provider:string uid:string user_id:integer

A user will have one or more authorizations, and when someone tries to login using a provider, we simply look at the authorizations within the database and look for one which matches the uid and provider fields. This way, we also enable users to have many providers, so they can later login using Facebook, or Twitter, or any other provider they have configured!

Add the following code to your app/models/user.rb file:

has_many :authorizations
validates :name, :email, :presence => true

This specifies that a user may have multiple authorizations, and that the name and email fields in the database are required.

Next, to your app/models/authorization.rb file, add:

belongs_to :user
validates :provider, :uid, :presence => true

Within this model, we designate that each authorization is bound to a specific user. We also set some validation as well.


Step 6: Adding a Bit of Logic to our Sessions Controller

Let’s add some code to our sessions controller so that it logs a user in or signs them up, depending on the case. Open app/controllers/sessions_controller.rb and modify the create method, like so:

def create
  auth_hash = request.env['omniauth.auth']

  @authorization = Authorization.find_by_provider_and_uid(auth_hash["provider"], auth_hash["uid"])
  if @authorization
    render :text => "Welcome back #{@authorization.user.name}! You have already signed up."
  else
    user = User.new :name => auth_hash["user_info"]["name"], :email => auth_hash["user_info"]["email"]
    user.authorizations.build :provider => auth_hash["provider"], :uid => auth_hash["uid"]
    user.save

    render :text => "Hi #{user.name}! You've signed up."
  end
end

This code clearly needs some refactoring, but we’ll deal with that later. Let’s review it first:

  • We check whether an authorization exists for that provider and that uid. If one exists, we welcome our user back.
  • If no authorization exists, we sign the user up. We create a new user with the name and email that the provider (Facebook in this case) gives us, and we associate an authorization with the provider and the uid we’re given.

Give it a test! Go to localhost:3000/auth/facebook and you should see “You’ve signed up”. If you refresh the page, you should now see “Welcome back”.


Step 7: Enabling Multiple Providers

The ideal scenario would be to allow a user to sign up using one provider, and later add another provider so he can have multiple options to login with. Our app doesn’t allow that for now. We need to refactor our code a bit. Change your sessions_controlller.rb’s create method to look like this:

def create
  auth_hash = request.env['omniauth.auth']

  if session[:user_id]
    # Means our user is signed in. Add the authorization to the user
    User.find(session[:user_id]).add_provider(auth_hash)

    render :text => "You can now login using #{auth_hash["provider"].capitalize} too!"
  else
    # Log him in or sign him up
    auth = Authorization.find_or_create(auth_hash)

    # Create the session
    session[:user_id] = auth.user.id

    render :text => "Welcome #{auth.user.name}!"
  end
end

Let’s review this:

  • If the user is already logged in, we’re going to add the provider they’re using to their account.
  • If they’re not logged in, we’re going to try and find a user with that provider, or create a new one if it’s necessary.

In order for the above code to work, we need to add some methods to our User and Authorization models. Open user.rb and add the following method:

def add_provider(auth_hash)
  # Check if the provider already exists, so we don't add it twice
  unless authorizations.find_by_provider_and_uid(auth_hash["provider"], auth_hash["uid"])
    Authorization.create :user => self, :provider => auth_hash["provider"], :uid => auth_hash["uid"]
  end
end

If the user doesn’t already have this provider associated with their account, we’ll go ahead and add it — simple. Now, add this method to your authorization.rb file:

def self.find_or_create(auth_hash)
  unless auth = find_by_provider_and_uid(auth_hash["provider"], auth_hash["uid"])
    user = User.create :name => auth_hash["user_info"]["name"], :email => auth_hash["user_info"]["email"]
    auth = create :user => user, :provider => auth_hash["provider"], :uid => auth_hash["uid"]
  end

  auth
end

In the code above, we attempt to find an authorization that matches the request, and if unsuccessful, we create a new user.

If you want to try this out locally, you’ll need a second authentication provider. You could use Twitter’s OAuth system, but, as I pointed out before, you’re going to need to use a different approach, since Twitter doesn’t allow using “localhost” as the callback URL’s domain (at least it doesn’t work for me). You could also try hosting your code on Heroku, which is perfect for a simple site like the one we’re creating.


Step 8: Some Extra Tweaks

Lastly, we need to, of course, allow users to log out. Add this piece of code to your sessions controller:

def destroy
  session[:user_id] = nil
  render :text => "You've logged out!"
end

We also need to create the applicable route (in routes.rb).

get '/logout', :to => 'sessions#destroy'

It’s as simple as that! If you browse to localhost:3000/logout, your session should be cleared, and you’ll be logged out. This will make it easier to try multiple accounts and providers. We also need to add a message that displays when users deny access to our app. If you remember, we added this route near the beginning of the tutorial. Now, we only need to add the method in the sessions controller:

def failure
  render :text => "Sorry, but you didn't allow access to our app!"
end

And last but not least, create the login page, where the user can click on the “Connect With Facebook” link. Open app/views/sessions/new.html.erb and add:

<%= link_to "Connect With Facebook", "/auth/facebook" %>

If you go to localhost:3000/login you’ll see a link that will redirect you to the Facebook authentication page.


Conclusion

I hope this article has provided you with a brief example of how Omniauth works. It’s a considerably powerful gem, and allows you to create websites that don’t require users to sign up, which is always a plus! You can learn about Omniauth on GitHub.

Let me us know if you have any questions!


June 21 2011

13:15

Set Up An Ubuntu Local Development Machine For Ruby On Rails

Advertisement in Set Up An Ubuntu Local Development Machine For Ruby On Rails
 in Set Up An Ubuntu Local Development Machine For Ruby On Rails  in Set Up An Ubuntu Local Development Machine For Ruby On Rails  in Set Up An Ubuntu Local Development Machine For Ruby On Rails

So, you want to develop Ruby on Rails applications? While loads of (introductory) tutorials are available for developing Ruby on Rails applications, there seems to be some uncertainty about setting up a lean and up-to-date local development environment.

This tutorial will guide you through the steps of setting up an Ubuntu local development machine for Ruby on Rails. Part 2 of this tutorial, which will be published here later, will help you through the steps to set up an Ubuntu VPS. For now, knowing that VPS stands for virtual private server is sufficient. It will be able to host your newly developed Ruby on Rails applications. But let’s focus on the local development machine first.

Bf Frontpage in Set Up An Ubuntu Local Development Machine For Ruby On Rails

Ruby On Rails? Ubuntu?

What are Ruby on Rails and Ubuntu? In short, Ruby on Rails is a Web development framework that lets you create Web applications using the Ruby programming language. As the official website states, “Ruby on Rails is an open-source Web framework that’s optimized for programmer happiness and sustainable productivity. It lets you write beautiful code by favoring convention over configuration.”

Ubuntu, meanwhile, is a “Debian-derived Linux distribution that focuses on usability.” It has been the most popular Linux distribution for the last couple of years. And even better, both Ruby on Rails and Ubuntu are open source and, therefore, completely free to use.

Bf Ubuntu-300x79 in Set Up An Ubuntu Local Development Machine For Ruby On Rails

A Quick Overview

In this tutorial, we’ll install Ruby and RubyGems using the Ruby Version Manager (RVM) script. And we’ll install Rails and Capistrano in turn using RubyGems. The machine will also feature version control, provided by Git and a PostgreSQL database. A fresh installation of Ubuntu and a working Internet connection are assumed, but these steps should work on most (Debian- and Ubuntu-based) Linux distributions.

At the time of writing, the latest versions are Ubuntu 10.10, Ruby 1.9.2 and Rails 3.0.7. This tutorial was also tested on Ubuntu 10.04 and the upcoming Ubuntu 11.04 release.

During this tutorial, we will make extensive use of the Linux command line. Therefore, I have added a small glossary at the end of this article describing the relevant Linux commands.

Getting Up To Date

First, let’s get up to date. Log into your machine as a user with administrative (or sudo) rights, and open a terminal window. The commands rendered below need to be entered in this terminal window. The dollar sign ($) is your command prompt, and the rest is as simple as typing the command and hitting “Enter.”

The first three commands will then update the package lists, upgrade currently installed packages, and install new packages and delete obsolete packages. This will give you a machine that is fully up to date. The final command will reboot the machine, which is good practice after updating a large number of packages.

$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get dist-upgrade
$ sudo reboot

Prepare Your Machine For RVM

After the machine has rebooted, log back in and open a terminal window. The RVM script needs some packages in order to be installed, namely Curl and Git. Curl is a tool to transfer data using a range of protocols (such as HTTP and FTP). And “Git is a free and open-source distributed version control system, designed to handle everything from small to very large projects with speed and efficiency.” Git is the choice for version control among most Ruby on Rails developers.

$ sudo apt-get install curl
$ sudo apt-get install git-core

Bf Git in Set Up An Ubuntu Local Development Machine For Ruby On Rails

Configure Git

Git will be used by the RVM script, and we’ll be using it in part 2 of this tutorial. So, after installing the packages, let’s take a little time to configure it. Configuring Git is easy: just provide a user name and email address.

$ git config --global user.name "Your Name"
$ git config --global user.email your-email@address.com

For example:

$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@mail.com

Install RVM

Now we can install RVM. RVM stands for Ruby version manager and “is a command-line tool that allows you to easily install, manage and work with multiple Ruby environments, from interpreters to sets of Gems.” The following command takes care of the installation of the script. RVM will get installed in the home directory of the currently logged-in user.

$ bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)

Bf Rvm in Set Up An Ubuntu Local Development Machine For Ruby On Rails

Navigate to the home directory, and edit the user bash profile. This ensures that the RVM script gets loaded every time the corresponding user logs in. To edit the bash profile, we’ll use Nano. Nano is a simple command-line text editor, and we will use it again in this tutorial.

$ cd
$ nano .bashrc

Add the following line to the end of the user bash profile. After you have made the changes, save the file by pressing CTRL + O, and exit Nano by pressing CTRL + X. If you ever want to exit Nano without saving changes, hit CTRL + X and then N.

[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm"

Manually load the script into the current shell session with the following command or open a new terminal window. This way, the rvm command will be made available.

$ source .bashrc

You can verify whether the RVM script is working by entering the following command:

$ type rvm | head -1

If everything is set up correctly, the shell should return that rvm is a function. If it doesn’t, go over to the RVM website and look under “Troubleshooting your install” to see what you can do to make it work.

Prepare Your Machine For Ruby And RubyGems

RVM comes with a handy command to view the dependencies that are needed to compile and install Ruby and RubyGems from source.

$ rvm notes

See the dependencies listed under the regular version of Ruby, and install these. Some packages might already be installed.

$ sudo apt-get install build-essential bison openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-0 libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev

Install Ruby And RubyGems Using RVM

First, we have Ruby, “a dynamic, open-source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write.”

Then we have RubyGems. This is “the premier Ruby packaging system. It provides a standard format for distributing Ruby programs and libraries, an easy-to-use tool for managing the installation of Gem packages, a Gem server utility for serving Gems from any machine where RubyGems is installed, and a standard way of publishing Gem packages.”

Bf Ruby in Set Up An Ubuntu Local Development Machine For Ruby On Rails

Like the RVM command described above, there is also a command to see what versions of Ruby are available for installation using RVM. Have a look at the available Ruby versions using this command:

$ rvm list known

Install a regular version of Ruby. Because Ruby gets compiled from source, this step might take a while.

$ rvm install 1.9.2

Start using the installed Ruby, and set this version as a default.

$ rvm --default use 1.9.2

Check the Ruby and RubyGems versions to see whether they have been properly installed.

$ ruby -v
$ gem -v

If necessary, manually updating RubyGems and the Gems is possible.

$ gem update --system
$ gem update

Install Rails Using RubyGems

Rails Gem itself is all that’s left for Ruby to be put on Rails. Installing this is one of the easiest parts of this tutorial. It is installed using RubyGems, invoked by the gem command. When the installation finishes, check the Rails version to see whether Rails has been properly installed.

$ gem install rails
$ rails -v

Bf Rails-252x300 in Set Up An Ubuntu Local Development Machine For Ruby On Rails

Install Capistrano Using RubyGems

Capistrano is “an open-source tool for running scripts on multiple servers. Its main use is deploying Web applications. It automates the process of making a new version of an application available on one or more Web servers, including supporting tasks such as changing databases.” You can install Capistrano using RubyGems. Check the Capistrano version to see whether it has been properly installed.

$ gem install capistrano
$ cap -V

Install PostgreSQL

PostgreSQL is “a sophisticated object-relational DBMS, supporting almost all SQL constructs, including subselects, transactions, and user-defined types and functions.” Install PostgreSQL together with a dependency. This dependency is needed to install the pg Gem later on, which is responsible for the connection between PostgreSQL and Ruby on Rails.

$ sudo apt-get install postgresql libpq-dev

Bf Postgresql in Set Up An Ubuntu Local Development Machine For Ruby On Rails

Configure PostgreSQL

When the packages have been installed, move on to configuring PostgreSQL by securing pSQL. pSQL is the PostgreSQL interactive terminal, and it is used for administrative database tasks.

By default pSQL does not require a password for you to log in. We’ll change this by editing the authentication method and then reloading the PostgreSQL configuration. But first, assign a password to super-user postgres. Log into pSQL, assign a safe password to postgres, and then log out of pSQL.

$ sudo -u postgres psql
# \password postgres
# \q

Now modify the authentication configuration by changing ident to md5. This ensures that a password is needed to log into pSQL and that the password is encrypted. The two lines that need to be edited can be found near the end of the configuration file. After that, reload the changed configuration into PostgreSQL.

$ sudo nano /etc/postgresql/8.4/main/pg_hba.conf
$ sudo /etc/init.d/postgresql reload

Most other PostgreSQL settings are stored in another configuration file. These settings can also be optimized, but that is beyond the scope of this tutorial. Keep in mind that a reload of the PostgreSQL configuration is required in order for changes to become active.

$ sudo nano /etc/postgresql/8.4/main/postgresql.conf

The installation of the local development machine is now done.

Testing The Set-Up

To make sure everything works, let’s develop a really small application and see a bit of Ruby on Rails in action. This process covers the following steps:

  • Create a database user for the test application,
  • Create a database for the test application,
  • Create a test application using PostgreSQL as the database,
  • Install the necessary Gems for the test application,
  • Configure the database connections for the test application,
  • Generate a simple scaffold for the test application,
  • Migrate the results of the scaffold to the test application database,
  • Start the built-in server,
  • Check the test application in a Web browser,
  • Stop the built-in server.

Once we have verified that everything works, we go through the following steps:

  • Delete the database for the test application,
  • Delete the database user for the test application,
  • Remove the test application.

All of these steps should be performed on the local development machine. The conventions used to test the VPS are as follows (the database user name and database name derive from the name of the application):

Box 1.1

Name of application: test_app

Name of database user: test_app

Password of database user: apple

Name of database: test_app_development

First, create a database user for the test application using the createuser command. We are using postgres as the admin (or super-user) for PostgreSQL. The P flag allows us to provide a password. The > sign stands for the questions that will be prompted.

$ sudo -u postgres createuser -P
> Enter name of role to add: test_app
> Enter password for new role: apple
> Enter it again: apple
> Shall the new role be a superuser? (y/n) n
> Shall the new role be allowed to create databases? (y/n) n
> Shall the new role be allowed to create more new roles? (y/n) n
> Password: your-postgres-user-password

Then, create a database for the test application that is owned by the test application user. While we could use Rake to create a database, we will use PostgreSQL, so that we learn some basic PostgreSQL administration. Create a new database by invoking the createdb command in conjunction with the O flag, the database user name and the new database name itself. The addition of development at the end makes it the default database name. Here, you will be prompted for the PostgreSQL super-user password again.

$ sudo -u postgres createdb -O test_app test_app_development
> Password: your-postgres-user-password

Now that the database has been set up, it is time to create the actual Ruby on Rails application. Navigate to your home directory, and create a new Rails application, named test_app, using PostgreSQL as the database back end. The d flag allows us to specify the preferred database software.

$ cd
$ rails new test_app -d postgresql

Go into the Rails application directory, and install the necessary Gems using Bundler. Bundler takes care of “an application’s dependencies through its entire life across many machines systematically and repeatably,” and it “works out of the box with Rails 3.”

$ cd test_app
$ bundle install

Use Nano to edit the database configuration file by adding apple as a password under the development database configuration. Because we have followed convention, described in Box 1.1 above, the database user name and database name have already been taken care of.

$ nano config/database.yml

Now generate a basic scaffold. This will create a User model and a users controller. The inputs will consist of a name and an email address, which are both strings in the PostgreSQL database.

$ rails generate scaffold User name:string email:string

Use Rake to migrate the scaffold to the development database. Rake is an acronym for Ruby Make. It is a “simple Ruby build program with capabilities similar to Make,” which allows you to create and migrate databases.

$ rake db:migrate

By now, it is time to check the (working) application in a Web browser. Start the built-in server, and use a Web browser to navigate to http://localhost:3000/. In particular, look at the application’s environment, and then look at http://localhost:3000/users. Create, edit, view and delete some users.

$ rails server

When everything appears to be working correctly, you can stop the built-in server.

$ press CTRL+C

If everything has worked, then the test application database and test application database user can be removed. The dropdb command removes a PostgreSQL database.

$ sudo -u postgres dropdb test_app_development
> Password: your-postgres-user-password

The dropuser command removes a PostgreSQL user.

$ sudo -u postgres dropuser
> Enter name of role to drop: test_app
> Password: your-postgres-user-password

Finally, navigate to your home directory, and recursively remove the test application. This leaves you with a fresh local development machine, ready for developing Ruby on Rails applications.

$ cd
$ rm -r test_app

In part 2 of this tutorial, which will be published here later, we will help you through the steps necessary to set up an Ubuntu VPS that is capable of hosting (multiple) Ruby on Rails applications.

Linux Command Line Glossary

The relevant Linux commands for this tutorial are listed below in alphabetical order. A Linux command usually takes the form of command -option(s) argument(s). For example, rm -r test_app. For a more detailed description, use the manual pages, which can be accessed using man [command].

  • sudo [command]Used to execute a command as an administrative user.
  • apt-get dist-upgradeIn addition to performing the function of upgrade, this is used to intelligently handle dependencies.
  • apt-get install [package]Used to install (or upgrade) packages.
  • apt-get updateUsed to resynchronize the package index files from their sources.
  • apt-get upgradeUsed to install the newest versions of all packages currently installed.
  • bash < <( curl [location] )A combination of commands for obtaining and executing a script (from the Internet).
  • cd [location]Used to change the current working directory. Without an argument, it goes to the user’s home directory.
  • nano [file]Used to edit configuration files.
  • rebootUsed to reboot the system.
  • rm -r [directory]Used to remove a directory (recursively).
  • source [script]Used to force bash to read a specified script.
  • type [command]Used to display the kind of command that the shell will execute.

References

Further Learning

(al)


© David Boot for Smashing Magazine, 2011. | Permalink | Post a comment | Smashing Shop | Smashing Network | About Us
Post tags: Ruby on Rails, Ubuntu

Sponsored post
feedback2020-admin
20:51

March 19 2011

19:45

Ruby for Newbies: Working with Gems


Ruby is a one of the most popular languages used on the web. We’ve started a new Session here on Nettuts+ that will introduce you to Ruby, as well as the great frameworks and tools that go along with Ruby development. Today, we’ll look at the awesome packaging system that Ruby provides for distributing programs and libraries: Gems.


View Screencast


Press the HD button for a clearer picture.
Subscribe to our YouTube page to watch all of the video tutorials!

Step 1: What are Gems?

It’s pretty simple, really. You can think of a Ruby Gem as a library or plug-in. It’s some functionality that you’ll install to fill a specific need. If that sounds vague, here are some practical problems that gems solve:

  • Need to interface with Amazon S3?
  • Want a quick-n-easy REST framework?
  • Need to send emails?
  • Want to set up a web server?
  • Need a testing framework (or three)?
  • Want to convert Markdown to HTML?

That’s just a few of the things you can do with gems.

In short, there’s a gem for that.


Span 2: Installing the RubyGems Library

Before we can install and use gems we need to install the RubyGems library. Of course, you’ll need Ruby installed first, but you should have that by now.

If you’re on Ruby 1.9.* (what we’re using in this series), then you don’t have to worry about installing RubyGems; it’s built in. If you’ve decided to stick with Ruby 1.8.*, it’s not too hard to install. Just head over to the RubyGems download page, download the TAR or ZIP, open it up, and run ruby setup.rb in the terminal from that folder You might need admin privileges to do this (sudo on unix systems, start the command line with “Run as Administrator” on Windows). That’ll get you up and running.

If you think you might already have RubyGems installed, run gem -v to get the version number. The latest version is 1.6.2. If you’d like to upgrade, run gem update --system. Again, you might need admin privileges. I should mention that if you’re on Windows and installed Ruby via the RubyInstaller, you do have RubyGems installed.


Step 3: Installing a Gem

So, now that you’ve got the RubyGems library installed, you can use it to install whatever gems you please. How do you do this? Again, it’s pretty simple. The hard part is finding the gem you’d like to use; often, you can just google for whatever functionality you’re looking for. Once you find the gem, install it like this:

gem install GEM_NAME

It’s important to pay attention to the documentation for the gem, though. There may be some arguments you should add to that command; however, in most cases, that should get you through.

One more note about installing gems: you might notice that a gem’s documentation tells you to use sudo when installing it. If you’re on a Mac and using RVM (as you should be :) ), just leave sudo off. Using it will install the gem for all users on the computer, and it can cause problems with the multiple Ruby environments you might have with RVM.

As we go on in this series, we’ll use several Ruby gems, so you’ll get to see how they’ll work in a “real” project. If you want to try installing a few now, try the Markdown (maruku) gem or the Amazon S3 (aws-s3) gem.

gem install maruku
gem install aws-s3

Step 4: Using Gems

So, you’ve got your gems installed; what now? Well, use them, of course! There are two ways you can use gems. Some are stand-alone ruby programs that you’ll run (most often from the command line) to do something. The Rails gem is a great example of this. You run rails new PROJECT_NAME from the command line to generate a new rails project; then, you’ll use it at other times to generate models, controllers, etc. Then, there are gems that you’ll only use from inside projects of your own, like the Amazon S3 gem. It’s not much good on it’s own, but it’s pretty useful in conjunction with your code. If you want to use a gem from within your code, you’ll have to require it first. This is usually done at the top of the file.

require 'rubygems' # only necessary on Ruby 1.8
require 'aws/s3' # the S3 gem

I don’t believe we’ve discussed require before; Ruby doesn’t load everything by default, so you can use require to load extra libraries you want to use. We’ll see more of this as we go on.

Finally, some gems do both. The maruku gem will convert Markdown to HTML. I use it from the command line all the time:

maruku doc.markdown

It will convert the Markdown document to HTML. However, you can also use it from your code:

require 'maruku'

str = "#This is a title\n\n* some\n* list\n* items"
md  = Maruku.new(str)
md.to_html_document

Step 5: Using Bundler

Once you build a project, you might want to share it, or use it on another computer. However, anyone else who runs it will need to have all the right gems installed. Now, you can make the process of installing them easy with a project called Bundler. There’s a lot Bundler can do, but we’ll just scrape the surface right now.

First of all, Bundler is a gem itself; you can install it by running gem install bundler.

Then, in the root of your project, create a file named Gemfile. This will declare what gems you need for this project.

The first line(s) of your Gemfile will tell Bundler where to get your gems. Gems live in online repositories, so it will need to know where to get them. Most of the time, just using rubygems.org as your source will be sufficient, but you can have multiple sources if you want.

source "http;//rubygems.org"

Then, just list your gems like this:

gem "rails", "3.0.1"
gem "maruku"
gem "aws-s3", :require => "aws/s3"

Note that we can say what version of a gem we need if we do need a specific version. Also, notice the hash (we’ve left off the brackets because we can in this case) on the third gem. This tells Bundler how we need to require the gem. This is only necessary if two things are true: 1) a gem is required with a different name than the name it’s installed with, and 2) we are using Bundler to require the gems.

If you’ve got a lot of gems, you can use Bundler to require them all in your code. Just do this:

require 'bundler/setup'
Bundler.require(:default)

This will load up all those gems. Of course, this is much more useful when you’re using some of Bundler’s advanced configurations.


Conclusion: Coming Soon …

Last time, I asked you readers / watchers what you want to see next. You clearly said “Web stuff!” Next lesson, we’re going to move on to using the simple framework Sinatra to build a website. Until then!

January 30 2011

23:44

Build a Dropbox-like File Sharing Site with Ruby on Rails: Premium


In this massive and advanced Premium Nettuts+ tutorial, we’ll learn how to build a file-sharing web application, like Dropbox, using Ruby on Rails. Become a Premium member to read this tutorial, as well as hundreds of other advanced tutorials and screencasts.

Sign Up Page
Folder Deleted
Invite Form
Shared Folder View
Sign Up Page

Join Net Premium

NETTUTS+ Screencasts and Bonus Tutorials

For those unfamiliar, the family of Tuts+ sites runs a premium membership service. For $9 per month, you gain access to exclusive premium tutorials, screencasts, and freebies from Nettuts+, Psdtuts+, Phototuts+, Aetuts+, Audiotuts+, Vectortuts+, and CgTuts+ For the price of a pizza, you’ll learn from some of the best minds in the business. Become a Premium member to read this tutorial, as well as hundreds of other advanced tutorials and screencasts.

December 29 2010

22:15

Why Ruby?


Just because you didn’t get to go to that awesome conference doesn’t mean that you can’t still watch the lectures! Each week, we feature one recommended web development lecture on Nettuts+.

In this recent lecture from Ruby Conf 2010, David Hansson, the creator of Ruby on Rails, focuses less on coding techniques, and more on the Ruby philosophy, in general. What makes a language like Ruby preferable to its peers? David provides his answer.

November 23 2010

14:21

Ruby for Newbies: Conditional Statements and Loops


Ruby is a one of the most popular languages used on the web. We’ve started a new screencast series here on Nettuts+ that will introduce you to Ruby, as well as the great frameworks and tools that go along with Ruby development. In this chapter, we’ll be looking at how conditional statements and loops work in Ruby.


Catch Up


View Screencast

Click the HD button for a clearer picture.

Subscribe to our YouTube page to watch all of the video tutorials!


Conditional #1: If Statement

The if statement is one of the first types of branching you learn when programming. You can guess what it means: if this is true, do one thing; if it’s not, do something else. In Ruby, these are pretty easy to write:

name = "Andrew"

if name == "Andrew"
	puts "Hello Andrew"
end

if name == "Andrew"
	puts "Hello Andrew"
else
	puts "Hello someone else"
end

After the keyword if, code in your conditional statement. After that comes the code to execute if the condition returns true. You close the statement with the end keyword. If you’d like, you can squeeze an else statement in there, which will predictably execute if the condition is false.

elsif

It’s not hard to check for multiple conditions. Just put as many elsif statements as you’d like between the if and else statements. Yes, that’s elsif, a marriage of else and if.

order = { :size => "medium" }

def make_medium_cofee
	puts "making medium statement"
end

#assume other functions

if order[:size] == "small"
	make_small_coffee;
elsif order[:size] == "medium"
	make_medium_coffee;
elsif order[:size] == "large"
	make_large_coffee;
else
    make_coffee;
end

As I mentioned, you can have as many elsif conditions and their corresponding code blocks as you want.

Statements vs. Expressions

Most programming languages make a distinction between statements and expressions. A statements is a code construct that doens’t evaluate to a certain value. An expression is a code construct does return a value. For example, calling a function is an expression, because it returns a value. However, an if statement is exactly that, a statement, because it does not return a value. This means that you can’t do this in your JavaScript:

message = if (someTruthyValue) {
		"this is true";
	} else {
		"this is false";
	}

Obviously, you can’t do this because the if statement does not return a value that you can assign to message.

However, you can do this with Ruby, because statements are actually expressions, meaning they return a value. So we can do this

message = if order[:size] == "small"
        "making a small"
    elsif order[:size] == "medium"
        "making a medium"
    else
        "making coffee"
    end

Whichever block of code is executed will become the value of message.

If as a Modifier

If you don’t have any elsif or else clauses, and your if statement has only one line, you can use it as a modifier to a “normal” line.

puts "making coffee" if customer.would_like_coffee?

Conditional #2: Unless Statement

In most programming languages, we want to reverse the return of the conditional expression, we have to negate it, usually with the bang (!) operator.

engine_on = true

if !engine_on   # meaning "if not engine_on"
	puts "servicing engine"  #should not be put, because "not engine_on" is false
end

However, Ruby has a really nice unless operator, that keeps us from having to do that, while giving us much more readable code:

unless engine_on  # "unless engine_on" is better than "if not engine_on"
	"servicing engine"
end

Just like if, you can use unless as a modifier:

puts "servicing engine" unless engine_on

Conditional #3: Case / When Statement

If you’ve got a lot of options to work through, using if/elsif/else might be somewhat wordy. Try the case statement.

hour = 15

case
when hour < 12
	puts "Good Morning"
when hour > 12 && hour < 17
	puts "Good Afternoon"
else
	puts "Good Evening"
end

It’s kinda-sorta-maybe like a switch/case statement in JavaScript (or other languages), except that there’s no one variable you’re evaluating. Inside the case/end keywords, you can put as many when statements as you’d like. Follow that when by the conditional expression, and then the lines of code go after it. Just like the if statement, the case statement is really an expression, so you can assign it to an expression and capture a returned value.

hour = 15

message = case
    when hour < 12
        "Good Morning"
    when hour > 12 && hour < 17
        "Good Afternoon"
    else
        "Good Evening"
    end

puts message

Breaking Up Expressions

If you’re familiar with JavaScript, you’ll know that the blocks of code in an if statement are surrounded by curly braces. We don’t do this in Ruby, so it may seem like Ruby is dependant on the whitespace. Nothing could be further from the truth (take that, pythonistas :) ).

If we want write your statements as one-liners, have to separate the different parts of the statements … but how? Well, you can use semi-colons:

if name == "Andrew"; some_code;
else; some_code; end

If you don’t like the look of that (which I don’t), you can put the keyword then between the conditional expressions and the line of code.

if name == "Andrew" then sode_code; end

This also works for a case statement.

case
    when x > 20; puts "<20"
    when x < 20 then puts "<20"
end

Loop #1: While Loop

So, those are conditional statements (I mean, expressions). How about loops? Let’s look at while loops first.

A while loop will continue to execute until the condition stated is false:

arr = ["John", "George", "Paul", "Ringo"]
i = 0

while arr[i]
    puts arr[i]
    i += 1
end

Here we’re looping over an array; when arr[i] returns false (meaning there are no items left in the array), the loop will stop executing. Inside the loop, we print out the current item in the array, and them add one to our increment variable.

You can also use while as a modifier

arr = ["John", "George", "Paul", "Ringo"]
i = -1

puts arr[i += 1] while arr[i]

Loop #2: Until Loop

Just like unless is the opposite of if, until is the opposite of while. It will continue to loop until the condition is true:

days_left = 7;

until days_left == 0
    puts "there are still #{days_left} in the week"
    days_left -= 1
end

And of course, it’s a modifier, too.

days_left = 8

puts "there are still #{days_left -= 1} in the week" until days_left == 1

Loop #3: For Loop

Yes, Ruby has a for loop. No, it’s not like the for loop in other languages. It acts like a foreach loop, for looping over the values in an array or hash:

arr = ["John", "George", "Paul", "Ringo"]

for item in arr
    puts item
end

If you’re looping over a hash, you can use two variable names, one for the key and one for the value:

joe = { :name => "Joe", :age => 30, :job => "plumber" }

for key, val in joe
    puts "#{key} is #{val}"
end

That’s it!

I hope you’re enjoying our Ruby for Newbies Screencast series. If there’s something you’d like to see, let me know in the comments! (And if you’re not watching the videos, you should be. There’s a screencast-only bonus at the end of each one.)

October 19 2010

19:20

Using Unobtrusive JavaScript and AJAX with Rails 3


As I mentioned in my previous Ruby on Rails tutorial, Unobtrusive JavaScript (UJS) is one of the coolest new features in Rails 3. UJS allows Rails-generated code to be much cleaner, helps separate your JavaScript logic from your HTML layouts, and uncouples Rails from the Prototype JavaScript library. In this tutorial, we’re going to look at these features and learn how to use them in a simple Rails 3 application.


Background: What is Unobtrusive JavaScript?

To start off, what exactly is UJS? Simply, UJS is JavaScript that is separated from your HTML markup. The easiest way to describe UJS is with an example. Take an onclick event handler; we could add it obtrusively:

<a href='#' onclick='alert("Inline Javscript")'>Link</a>

Or we could add it unobtrusively by attaching the event to the link (using jQuery in this example):

<a href='#'>Link</a>
<script>
$('a').bind('click', function() {
    alert('Unobtrusive!');
}
</script>

As mentioned in my introduction, this second method has a variety of benefits, including easier debugging and cleaner code.

“Rails 3, on the other hand, is JavaScript framework agnostic. In other words, you can use your JavaScript framework of choice, provided a Rails UJS implementation exists for that framework.”

Up until version 3, Ruby on Rails generated obtrusive JavaScript. The resulting code wasn’t clean, but even worse, it was tightly coupled to the Prototype JavaScript framework. This meant that unless you created a plugin or hacked Rails, you had to use the Prototype library with Rail’s JavaScript helper methods.

Rails 3, on the other hand, is JavaScript framework agnostic. In other words, you can use your JavaScript framework of choice, provided a Rails UJS implementation exists for that framework. The current UJS implementations include the following:

Rails 3 now implements all of its JavaScript Helper functionality (AJAX submits, confirmation prompts, etc) unobtrusively by adding the following HTML 5 custom attributes to HTML elements.

  • data-method – the REST method to use in form submissions.
  • data-confirm – the confirmation message to use before performing some action.
  • data-remote – if true, submit via AJAX.
  • data-disable-with – disables form elements during a form submission

For example, this link tag

<td><a href="/posts/2" class="delete_post" data-confirm="Are you sure?" data-method="delete" data-remote="true" rel="nofollow">Destroy</a></td>

would send an AJAX delete request after asking the user “Are you sure?.”

You can imagine how much harder to read that would be if all that JavaScript was inline.

Now that we’ve reviewed UJS and how Rails implements UJS, let’s set up a project and look at some specific applications. We’ll be using the jQuery library and UJS implementation in this tutorial.


Step 1: Setting up the Project

Since we’re creating a new project from scratch, the first thing we need to do is create the project by typing the following:

	rails new blog --skip-prototype

Notice that I’m instructing Rails to skip the prototype JavaScript file, since I’m going to be using the jQuery library.

Let’s start the server just to make sure everything appears to be working.

And, voila!

Now that we’ve set up our project, we need to add jQuery and the jQuery UJS to our project. You are free to organize your JavaScript however you want, but the Rails convention for structuring your JavaScript files is as follows (all these files go in public/javascripts):

  • framework JavaScript file (jquery.js, prototype.js, or mootools.js)
  • rails.js – the code implementing rails UJS (for whatever framework you’ve chosen)
  • application.js – your application JavaScript

If you haven’t already, download jquery.js (or refer to a CDN) and rails.js and include them in your public/javascripts directory.

The last thing we need to do to get up and running is to actually tell Rails to include these js files on each of our pages. To do this, open application.rb in your config directory and add the following line

config.action_view.JavaScript_expansions[:defaults] = %w(jquery rails application)

This configuration item tells Rails to include the three JavaScript files mentioned above by default.

Alternatively, you could grab jQuery from a CDN (i.e. http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js) by manually included a script tag pointing to the correct location. If you do this, be sure to remove ‘jquery’ from the JavaScript_expansions configuration item.


Step 2: Generating Some Code

To demonstrate the rails UJS functionality, we’re first going to have to have some code to work with. For this demo we’re just going to have a simple Post object. Let’s generate that now

	rails generate scaffold Post name:string title:string content:text

And then let’s migrate our database to create the posts table.

	rake db:migrate

Ok, we’re good to go! If we navigate to http://localhost:3000/posts/new, we should see a form to create a new Post.

Ok, it’s all working! Now let’s dig in and see how to use the UJS and AJAX functionality baked into Rails.


Step 3: Adding AJAX

Now that all the required JavaScript files are being included, we can actually start using Rails 3 to implement some AJAX functionality. Although you can write all of the custom JavaScript that you want, Rails provides some nice built-in methods that you can use to easily perform AJAX calls and other JavaScript actions.

Let’s look at a couple of commonly used rails helpers and the JavaScript they generate

AJAX Form Submission and Javascript ERB Files

If we look at our Posts form, we can see that whenever we create or edit a Post, the form is manually submitted and then we’re redirected to a read-only view of that Post. What if we wanted to submit that form via AJAX instead of using a manual submission?

Rails 3 makes it easy to convert any form to AJAX. First, open your _form.html.erb partial in app/views/posts, and change the first line from:

<%= form_for(@post) do |f| %>

to

<%= form_for(@post, :remote => true) do |f| %>

Prior to Rails 3, adding :remote => true would have generated a bunch of inline JavaScript inside the form tag, but with Rails 3 UJS, the only change is the addition of an HTML 5 custom attribute. Can you spot it?

<form accept-charset="UTF-8" action="/posts" class="new_post" data-remote="true" id="new_post" method="post">

The attribute is data-remote="true", and the Rails UJS JavaScript binds to any forms with that attribute and submits them via AJAX instead of a traditional POST.

That’s all that’s needed to do the AJAX submit, but how do we perform a callback after the AJAX call returns?

The most common way of handling a return from an AJAX call is through the use of JavaScript ERB files. These work exactly like your normal ERB files, but contain JavaScript code instead of HTML. Let’s try it out.

The first thing we need to do is to tell our controller how to respond to AJAX requests. In posts_controller.rb (app/controllers) we can tell our controller to respond to an AJAX request by adding

format.js

in each respond_to block that we are going to call via AJAX. For example, we could update the create action to look like this:

def create
    @post = Post.new(params[:post])

    respond_to do |format|
      if @post.save
        format.html { redirect_to(@post, :notice => 'Post created.') }
        format.js
      else
        format.html { render :action => "new" }
        format.js
      end
    end
end

Because we didn’t specify any options in the respond_to block, Rails will respond to JavaScript requests by loading a .js ERB with the same name as the controller action (create.js.erb, in this case).

Now that our controller knows how to handle AJAX calls, we need to create our views. For the current example, add create.js.erb in your app/views/posts directory. This file will be rendered and the JavaScript inside will be executed when the call finishes. For now, we’ll simply overwrite the form tag with the title and contents of the blog post:

	$('body').html("<h1><%= escape_JavaScript(@post.title) %></h1>").append("<%= escape_JavaScript(@post.content) %>");

Now if we create a new Post we get the following on the screen. Success!

The advantage of this method is that you can intersperse ruby code that you set up in your controller with your JavaScript, making it really easy to manipulate your view with the results of a request.

AJAX Callbacks Using Custom JavaScript Events

Each Rails UJS implementation also provides another way to add callbacks to our AJAX calls – custom JavaScript events. Let’s look at another example. On our Posts index view (http://localhost:3000/posts/), we can see that each post can be deleted via a delete link.

Let’s AJAXify our link by adding :remote=>true and additionally giving it a CSS class so we can easily find this POST using a CSS selector.

<td><%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete, :remote=>true, :class=>'delete_post' %></td>

Which produces the following output:

<td><a href="/posts/2" class="delete_post" data-confirm="Are you sure?" data-method="delete" rel="nofollow">Destroy</a></td>

Each rails UJS AJAX call provides six custom events that can be attached to:

  • ajax:before – right before ajax call
  • ajax:loading – before ajax call, but after XmlHttpRequest object is created)
  • ajax:success – successful ajax call
  • ajax:failure – failed ajax call
  • ajax:complete – completion of ajax call (after ajax:success and ajax:failure)
  • ajax:after – after ajax call is sent (note: not after it returns)

In our case we’ll add an event listener to the ajax:success event on our delete links, and make the deleted post fade out rather than reloading the page. We’ll add the following JavaScript to our application.js file.

	$('.deletePost').bind('ajax:success', function() {
		$(this).closest('tr').fadeOut();
	});

We’ll also need to tell our posts_controller not to try to render a view after it finishes deleting the post.

  def destroy
    @post = Post.find(params[:id])
    @post.destroy

    respond_to do |format|
      format.html { redirect_to(posts_url) }
      format.js   { render :nothing => true }
    end

Now when we delete a Post it will gradually fade out.


Conclusion

Well, there you have it. Now you know how to make AJAX calls using Rails 3 UJS. While the examples explained were simple, you can use these same techniques to add all kinds of interactivity to your project. I hope you’ll agree that it’s a big improvement over previous versions, and that you’ll try it out on your next Rails project.

What techniques do you use when implementing AJAX in Rails?

February 09 2010

19:09
Older posts are this way If this message doesn't go away, click anywhere on the page to continue loading posts.
Could not load more posts
Maybe Soup is currently being updated? I'll try again automatically in a few seconds...
Just a second, loading more posts...
You've reached the end.
(PRO)
No Soup for you

Don't be the product, buy the product!

close
YES, I want to SOUP ●UP for ...