Wednesday 17 October 2012

Zip the files and download all in rails 3

In one of my project client asked me to give download all link for one folder which contains files. For that i have used this method which is using Tempfile to store files temperorily, zip files together using 'rubyzip' gem.

use this in your gem file,

gem 'rubyzip'

run bundle install

#controller

def download_all
      @records = Record.all
      if !@records.blank?
      file_name = 'download_files.zip'
      t = Tempfile.new("temp-filename-#{Time.now}")
      Zip::ZipOutputStream.open(t.path) do |z|
        @records.each do |img|
          file_path = img.image_name.to_s
          z.put_next_entry(file_path)
          z.print IO.read(img.image_name.path)
        end
      end
      send_file t.path, :type => 'application/zip', :x_sendfile=>true,
        :disposition => 'attachment',
        :filename => file_name
      t.close
    end
  end






Thank you guys..

Wednesday 9 May 2012

Ruby on Rails 3 Testing with Cucumber

Cucumber is used for Behaviour Driven Development.
Cucumber lets software development teams describe how software should behave in plain text. The text is written in a business-readable domain-specific language and serves as documentation, automated tests and development-aid - all rolled into one format.
Cucumber works with Ruby, Java, .NET, Flex or web applications written in any language. It has been translated to over 40 spoken languages.
Install cucumber for Rails 3:
Install Cucumber, Rspec-rails and capybara gem

sudo gem install cucumber-rails
sudo gem install database_cleaner
sudo gem install rspec-rails
sudo gem install capybara
  • Cucumber is a behavior driven development (BDD) framework in particular good for integration and functional tests
  • RSpec is a behavior driven development (BDD) framework for low level testing in the Ruby language
  • database_cleaner performs DB cleanup in testing
  • capybara simulating a browser, automating a browser or setting expectations using the matchers.



Using Cucumber to test rails 3 application:


  • Create a new Rails application store
$rails new store -d mysql
  • Edit the Gemfile
Include the Cucumber gems in a Rails 3 application
 group :test, :development do
    gem 'rspec-rails'
    gem 'cucumber-rails'
     gem 'capybara'
     gem 'database_cleaner'
 end
  • bundle install
  • Install the cucumber skeleton files to a Rails 3 application.
$ rails generate cucumber:install 



The cucumber-rails generator creates the directories:
features/step_definitions
features/support
The cucumber-rails generator creates the files:
config/cucumber.yml
features/support/env.rb
lib/tasks/cucumber.rake
script/cucumber
$rake cucumber



Create cucumber features:



  • Create a Cucumber Feature for Rails 3 application testing
$vi features/manage_store.feature
  • Cucumber Feature is the business user testing specification written in plain English with a specific format
Feature Format
 Feature: ...
   In order ...
    Some Actor ...
   Should ...
 
   Scenarior: ...
      Given ...
      And ...

     When ...
     AND ...
 
     Then ...
     AND ...
Implement the testing steps and Rails model code for Cucumber on Rails :
  • Create Cucumber step definitions
$vi features/step_definitions/order_steps.rb
  • Cucumber uses regular expression to match string and pass it to the step definitions
  • Run Cucumber
$rake cucumber



An example might be the ability to manage companies:
Feature: Manage companies

 In order to keep track of companies
 
 A user

  Should be able to manage companies


Scenario: Create a new company

 Given I am logged in

 When I create a new company named Acme

 Then I should see that a company named Acme exists



features/

companies.feature

steps/

company_steps.rb



Given == Setup

Given "I am logged in" do

user = Factory(:user)

visits new_session_path

fills_in ‘Login’,

:with => user.login

fills_in ‘Password’, :with => user.password

clicks_button ‘Login’

end



Given "I am logged in" do

user = Factory(:user)

visits new_session_path

fills_in 'Login',

:with => user.login

fills_in 'Password', :with => user.password

clicks_button 'Login'

end



When == Change

When "I create a new company named $name" do |name|

visits new_company_path

fills_in 'Name', :with => name

clicks_button 'Create'

end


Then == Outcome

Then "I should see that a company named $name exists" do |name|

response.body.should =~ Regexp.new(name)

end



At every step you need to run cucumber and check for the result.

Tuesday 10 April 2012

Using Regular Expression in Ruby on Rails — Regexp for Password Validation

A regular expression (abbreviated as regexp or regex, with plural forms regexps, regexes, or regexen) is a string that describes or matches a set of strings, according to certain syntax rules. Regular expressions are used by many text editors and utilities to search and manipulate bodies of text based on certain patterns. Many programming languages support regular expressions for string manipulation. Ruby has a strong Regular Expression engine built directly as a class of Ruby Programming language as Regexp
Here we will go through an example which will validate the password string.
Lets say we have to implement the following validations to validate a password…
  • Password should contain atleast one integer.
  • Password should contain atleast one alphabet(either in downcase or upcase).
  • Password can have special characters from 20 to 7E ascii values.
  • Password should be minimum of 8 and maximum of 40 cahracters long.
To fulfill above requirements we can have a regular expression like…


/^(?=.*\d)(?=.*([a-z]|[A-Z]))([\x20-\x7E]){8,40}$/


in ruby programming language we can have a number of ways to define this regular expression as…
  • reg = Regexp.new(“^(?=.*\d)(?=.*([a-z]|[A-Z]))([\x20-\x7E]){8,40}$”)
or
  • reg = %r(^(?=.*\d)(?=.*([a-z]|[A-Z]))([\x20-\x7E]){8,40}$)
or simply
  • reg = /^(?=.*\d)(?=.*([a-z]|[A-Z]))([\x20-\x7E]){8,40}$/

Now look what exactly this regex is doing…
(?=.*\d) shows that the string should contain atleast one integer.
(?=.*([a-z]|[A-Z])) shows that the string should contain atleast one alphabet either from downcase or upcase.
([\x20-\x7E]) shows that string can have special characters of ascii values 20 to 7E.
{8,40} shows that string should be minimum of 8 to maximum of 40 cahracters long.
We can simply use this regular expression for manual handling of password in an action as…

 

def validate_password(password)

  reg = /^(?=.*\d)(?=.*([a-z]|[A-Z]))([\x20-\x7E]){8,40}$/

return (reg.match(password))? true : false

end
 

How to implement this regular expression in a model class in ruby on rails for password validation ?
To implement this regular expression in the model class in the rails way we can do it like…

class MyModel validates_format_of :password, :with => /^(?=.*\d)(?=.*([a-z]|[A-Z]))([\x20-\x7E]){8,40}$/ end




Thank you...

Monday 9 April 2012

Rails 3.2.3 has been released!

This release changes the default value of config.active_record.whitelist_attributes to true. This change only affects newly generated applications so it should not cause any backwards compatibility issues for users who are upgrading but it may affect some tutorials and introductory material. For more information see the mass assignment section of the ruby on rails security guide
Rails 3.2.3 also introduces a new option that allows you to control the behavior of remote forms when it comes to authenticity_token generation. If you want to fragment cache your forms, authenticity token will also get cached, which isn't acceptable. However, if you only use such forms with ajax, you can disable token generation, because it will be fetched from meta tag. Starting with 3.2.3, you have an option to stop generating authenticity_token in remote forms (ie. :remote => true is passed as an option), by setting config.action_view.embed_authenticity_token_in_remote_forms = false. Please note that this will break sending those forms with javascript disabled. If you choose to not generate the token in remote forms by default, you can still explicitly pass :authenticity_token => true when generating the form to bypass this setting. The option defaults to true, which means that existing apps are NOT affected.
We've also adjusted the dependencies on rack-cache and mail to address the recent security vulnerabilities with those libraries. If you are running a vulnerable version of mail or rack-cache you should update both gems to a safe version. There were also some regressions in the render method that were fixed in this version.

CHANGES since 3.2.2

Action Mailer
  • Upgrade mail version to 2.4.3 
Action Pack
  • Fix #5632, render :inline set the proper rendered format.
  • Fix textarea rendering when using plugins like HAML. Such plugins encode the first newline character in the content. This issue was introduced in https://github.com/rails/rails/pull/5191
  • Do not include the authenticity token in forms where remote: true as ajax forms use the meta-tag value DHH
  • Turn off verbose mode of rack-cache, we still have X-Rack-Cache to check that info. Closes #5245.
  • Fix #5238, rendered_format is not set when template is not rendered. 
  • Upgrade rack-cache to 1.2.
    Fixes layout rendering regression from 3.2.2
    Active Model
  • No changes
Active Record
  • Added find_or_create_by_{attribute}! dynamic method.
  • Whitelist all attribute assignment by default. Change the default for newly generated applications to whitelist all attribute assignment. Also update the generated model classes so users are reminded of the importance of attr_accessible.
  • Update ActiveRecord::AttributeMethods#attribute_present? to return false for empty strings.
  • Fix associations when using per class databases. 
  • Revert setting NOT NULL constraints in add_timestamps fxn
  • Fix mysql to use proper text types. Fixes #3931. 
  • Fix #5069 - Protect foreign key from mass assignment through association builder.
Active Resource
  • No changes
Active Support
  • No changes
Railties
  • No changes

SHA-1

  • SHA-1 (actionmailer-3.2.3.gem) = 04cd2772dd2d402ffb9d9dbf70f5f2256c598ab3
  • SHA-1 (actionpack-3.2.3.gem) = 06d51ebd0863e0075d9a3e89a2e48dcc262c4e0c
  • SHA-1 (activemodel-3.2.3.gem) = 3f648213b88bb3695e2bce38ff823be99535f401
  • SHA-1 (activerecord-3.2.3.gem) = a9810e79d720994abbe24aded2bcb783bb1649b4
  • SHA-1 (activeresource-3.2.3.gem) = 3d1de8a80122efbcf6c8b8dfc13a7ab644bb2ca3
  • SHA-1 (activesupport-3.2.3.gem) = 6a63d75c798fb87d081cbee9323c46bec4727490
  • SHA-1 (rails-3.2.3.gem) = 4db7e5c288f5260dc299d55ec2aad9a330b611fc
  • SHA-1 (railties-3.2.3.gem) = 39a887de71350ece12c784d3764b7be2c6659b32

Wednesday 28 March 2012

Database dumping to your rails application

To take database backup

$ mysqldump -u root -p[password] [dbname] > [backupfile.sql]


To dump all MySQL databases on the system, use the --all-databases shortcut

 $ mysqldump -u root -p[password] --all-databases > [backupfile.sql]


To restore database

$ mysql -u root -p [password] [database_to_restore] < [backupfile]

Saturday 24 March 2012

DEVISE – Authentication GEM for a Rails app

Comprises of 12 modules :

Database Authenticatable
Token Authenticatable
Omniauthable
Confirmable
Recoverable
Registerable
Rememberable
Trackable
Timeoutable
Validatable
Lockable
Encryptable

STEPS TO FOLLOW
https://github.com/plataformatec/devise

 1. Create project :
      rails new project_name

2. Create database :
      rake db:create

3. Gem ‘devise’  (paste it in gem file)

4. Bundle install

5. Generate scaffold :
      rails g scaffold name  attributes

6. Specify the route in routes.rb -> root:to => “name#index“

7. Migrate it :
     rake db:migrate

8. Rails generate devise:install

9. In config -> environments ->development -> add this line
     config.action_mailer.default_url_options = { :host => 'localhost:3000' }

10. In views ->application.html.erb -> paste some lines to create session

=> To create session :
<% if user_signed_in? %>
    Signed in as <%= current_user.email %>. Not you?
    <%= link_to "Sign out", destroy_user_session_path, :method => :delete %>
    <% else %>
    <%= link_to "Sign up", new_user_registration_path %>
 or <%= link_to "sign in", new_user_session_path %>
  <% end %>
      </div>
      <% flash.each do |name, msg| %>
        <%= content_tag :div, msg, :id => "flash_#{name}" %>
      <% end %>

11. Rails g devise User

12. Do some modifications in migration file of User based on our attributes
      and requirements.

13. Again do migration

14. Rake routes

15. Add filter in controller
      before_filter :authenticate_user!, :except => [:show, :index]

16. Rails g devise:views  ( to include views in our application)

17. In new.html.erb -> Add custom fields in registration

18. All error messages will be stored in
      config -> locales ->devise.en.yml

19. Config -> initializers ->devise.rb
     Uncomment ‘ config.encrypt:sha512 ‘

20. config -> development.rb -> do smtp settings  to send email
    config.action_mailer.delivery_method = :smtp

  config.action_mailer.smtp_settings = {
  :enable_starttls_auto  => true, 
  :address                      => 'smtp.gmail.com',
  :port                             => 587,
  :tls                                => true,
  :domain                        => 'gmail.com',
  :authentication             => :plain,
  :user_name                  => ‘xyz@gmail.com',
  :password                     => ‘xxxxxx'
}
end


Now start your server and work on secured application.     
     

Monday 19 March 2012

1 in 5 bosses reject candidates after seeing their Facebook profiles

 Jobseekers are being warned to be far more vigilant over what they reveal on social networking sites, as it could cost them their career.

A fifth of IT executives admitted they have rejected applicants because of what they have posted on social media.

The worrying news was revealed in the 2012 annual technology market survey conducted by Eurocom Worldwide, the Global PR Network, in association with UK PR agency partner, Six Degrees.

The annual study has previously found that almost 40 per cent of respondents' companies look at potential employees' profiles on social media sites - but this is the first clear evidence that candidates are being rejected because of them.

"The 21st-century human is learning that every action leaves an indelible digital trail," the Daily Mail quoted Mads Christensen, Network Director at Eurocom Worldwide, as saying.

"In the years ahead, many of us will be challenged by what we are making public in various social forums today.

"The fact that one in five applicants disqualify themselves from an interview because of content in the social media sphere is a warning to job seekers and a true indicator of the digital reality we now live in," Christensen said.

The survey also revealed that while nearly half of technology executives say that their firms will increase their expenditure on social media in the next 12 months, only 23 per cent say they can accurately measure the impact of the investment.

It said that 74 per cent of respondents consider online PR to be important for their company's search engine optimisation, with 37 per cent saying it is very important.

The Eurocom Worldwide technology confidence survey was conducted online by member agencies of Eurocom Worldwide during January and February 2012.

A total of 318 companies replied, with approximately 80 per cent from European countries and 11 per cent from the Americas.

The report also found that most popular social media platforms used by technology companies were LinkedIn (74 per cent), Twitter (67 per cent), Facebook (64 per cent) and YouTube (56 per cent).

Tuesday 13 March 2012

Rails 3.1 / Rack App Hosting with RVM, Passenger 3, Capistrano, Git and Apache

This guide supersedes a number of earlier guides, providing the details to get up and running with a rack based application from a basic ubuntu server VPS. It is a walkthrough of the steps taken, and it is advisable to first read the installation instructions provided by the software authors.
At the time of writing, the latest versions of the software in use are:
  • RVM: 1.9.0
  • Ruby: 1.9.2-p290
  • Passenger: 3.0.9
  • Rails: 3.1.1
  • Capistrano: 2.9.0
You may need to alter the versions in the steps below as some commands and paths contain explicit versions. The server used for hosting in the guide is an Ubuntu Lucid VPS, so tailor the steps to your platform accordingly. Also, substitute domainname, hostname and appname as appropriate for your environment.

RVM Multi User Install

RVM can be installed for multiple users by installing as root. This allows installations to be shared across different users, although different users can use which ever version they wish.
Log in as root and install using the preferred script:

bash < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer) 
 
In order for a user to use the multi user RVM installation the must belong to the rvm group. Also check that they do not have a ~/.rvm directory as this takes precedence over the multi user install for that user.

Create Passenger User

It is a good idea to create a passenger user on the server to install services as so that it is isolated from other users. You can also deploy your applications using this user. The passenger user needs sudo rights for installing packages using apt-get and running the passenger install script, and needs to be a member of the rvm group to use the multi user install.

sudo adduser passenger
sudo usermod -G passenger,www-data,sudo,rvm passenger
su - passenger 
 
You can remove the sudo right after completing the installation using the following:
sudo usermod -G passenger,www-data,rvm passenger
Generate a key pair for ssh too. On your client machine, create a key and use a string pass phrase:

ssh-keygen -v -t rsa -f passenger@domainname -C passenger@domainname 
 
This will create a private key called passenger@domainname and a public key called passenger@domainname.pub. Keep these somewhere safe.
You can register the public key into authorized_keys to allow key based ssh authentication. Run the following on your client machine:
scp passenger@domainname.pub passenger@hostname:~/.ssh/authorized_keys
Depending on the client and your preference, you can either enter the passphrase for you private key each time you connect, or run ssh-agent and register the key using ssh-add. To register the private key into your ssh agent on your client machine run the following and enter the passphrase when prompted:

ssh-add passenger@domainname 
 
You should now be able to ssh to the server without being challenged for the password, e.g:

ssh passenger@hostname

Passenger RVM Configuration

Note: if you previously had RVM installed as a single user you need to remove the old source line for $HOME/.rvm/scripts/rvm and move (or delete) the .rvm directory so that the system wide installation is picked up instead.
Log out and log in again as passenger to ensure the scripts work as expected. You can test RVM is available correctly by running:
type rvm | head -n1
You should then see the following output:

rvm is a function 
 
You can view the requirements for installing the different rubies by running rvm requirements.
To install the packages (requires sudo):
sudo apt-get install build-essential 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 automake libtool bison subversion
To install ruby 1.9.2:

rvm install 1.9.2
rvm use --default 1.9.2 
 
You can can now verify the ruby version and install some gems, e.g.:
ruby -v
gem install bundler rails

Passenger

Passenger is very easy to install. RVM provides some instructions specifically for passenger.
Install the gem and run the installation script. It will tell you what dependencies you are missing and how to install them:

gem install passenger
passenger-install-apache2-module 
 
Passenger provides some instructions on how to configure apache. I like to treat passenger as a mod for apache, allowing it to be enabled and disabled as required through the a2enmod and a2dismod commands respectively.
To enable passenger, create /etc/apache2/mods-available/passenger.load with the following contents:
LoadModule passenger_module /usr/local/rvm/gems/ruby-1.9.2-p290/gems/passenger-3.0.9/ext/apache2/mod_passenger.so
and /etc/apache2/mods-available/passenger.conf with the following contents:
PassengerRoot /usr/local/rvm/gems/ruby-1.9.2-p290/gems/passenger-3.0.9
PassengerRuby /usr/local/rvm/wrappers/ruby-1.9.2-p290/ruby
then enable the module and restart apache:

sudo a2enmod passenger
sudo /etc/init.d/apache2 restart

Apache

Each rack/rails application is made available through a virtual host directive in the apache configuration. The recommended way to do this is to create a file named after the site, e.g. domainname in /etc/apache2/sites-available and then enable and disable the site as required using the a2ensite and a2dissite commands respectively.
I prefer to put all web applications in /var/www and have users be able to create applications if they are a member of www-data:

sudo mkdir /var/www
sudo chown www-data:www-data /var/www
sudo chmod g+w /var/www

Hello World rack app

I find it useful to have a simple Hello World rack application to verify the rvm and passenger installation. The application can be run as a subdomain to allow testing and can be enabled and disabled as desired.
Create the necessary directory structure for a rack application:

cd /var/www
mkdir hw.domainname
cd hw.domainname
mkdir public
mkdir tmp 
 
Create /var/www/hw.domainname/config.ru with the following contents:
app = proc do |env|
  [200, { "Content-Type" => "text/html" }, ["hello, world"]]
end
run app 
 
Create /etc/apache2/sites-available/hw.domainname with the following contents:
<VirtualHost *:80>
    ServerName hw.domainname
    DocumentRoot /var/www/hw.domainname/public
    <Directory /var/www/hw.domainname/public>
        AllowOverride all
        Options -MultiViews
    </Directory>
</VirtualHost>
Enable the site, and then view it in your browser:
sudo a2ensite hw.domainname
sudo /etc/init.d/apache2 reload
This can then be disabled and reenabled if needed for debugging any issues at a later date:

sudo a2dissite hw.domainname
sudo /etc/init.d/apache2 reload

Rails app

You now need to create a virtual host for the rails app so that apache can handle the requests and pass off to passenger.
Create the necessary directory structure for a rails application (assuming its running as the domainname):
cd /var/www
mkdir domainname
Create /etc/apache2/sites-available/domainname with the following contents:
<VirtualHost *:80>
    ServerName domainname
    DocumentRoot /var/www/domainname/current/public
    <Directory /var/www/domainname/current/public>
        AllowOverride all
        Options -MultiViews
    </Directory>
</VirtualHost>
Enable the site, although there is nothing there to view until we have deployed it:
sudo a2ensite domainname
sudo /etc/init.d/apache2 reload

Capistrano

The following steps should be performed on your client machine to capify an existing rails application and deploy it.

Configuration

Make sure you have capistrano installed:
gem install capistrano
Initialise the rails application:
cd ~/dev/appname
capify .
This will generate some files, along with a sample config/deploy.rb. Replace the file contents with the following, using suitable values where applicable.
# RVM bootstrap
$:.unshift(File.expand_path('./lib', ENV['rvm_path']))
require 'rvm/capistrano'
set :rvm_ruby_string, '1.9.2-p290'

# bundler bootstrap
require 'bundler/capistrano'

# main details
set :application, "domainname"
role :web, "domainname"
role :app, "domainname"
role :db,  "domainname", :primary => true

# server details
default_run_options[:pty] = true
ssh_options[:forward_agent] = true
set :deploy_to, "/var/www/domainname"
set :deploy_via, :remote_cache
set :user, "passenger"
set :use_sudo, false

# repo details
set :scm, :git
set :scm_username, "passenger"
set :repository, "git@gitserver:domainname.git"
set :branch, "master"
set :git_enable_submodules, 1

# tasks
namespace :deploy do
  task :start, :roles => :app do
    run "touch #{current_path}/tmp/restart.txt"
  end

  task :stop, :roles => :app do
    # Do nothing.
  end

  desc "Restart Application"
  task :restart, :roles => :app do
    run "touch #{current_path}/tmp/restart.txt"
  end
end
Note: the above file supplies the rvm ruby version as 1.9.2-p290. It is advisable to be specific about the version here as if this were 1.9.2 and a newer ruby version is available you may start to receive errors in the capistrano deployment.

Deployment

The first time you deploy to the server you should run the deployment setup task:
cap deploy:setup
Thereafter you can deploy using:
cap deploy
Or if you have database migrations to run then use:
cap deploy:migrations
You may get some strange errors or failures when deploying. If you have followed the steps I have mentioned in this guide then hopefully you shouldn’t have many problems. Common problems are:
  • wrong permissions of /var/www
  • wrong permissions of passenger user
  • not having rvm installed for passenger user
  • not having the basic gems required to use capistrano on the server, simply install them as the passenger user

Monday 12 March 2012

A Hypermedia API Reading List

Originally, this post was titled "A RESTful Reading List," but please note that REST is over. Hypermedia API is the new nomenclature.


I'll be updating this post as I get new resources, so check back!

If you want to go from 'nothing to everything,' you can do it by reading just a few books, actually. I'm going to make all of these links affiliate. I purchase a lot of books myself, maybe suggesting things to you can help defray the cost of my massive backlog. All are easily searchable on Amazon if you're not comfortable with that.
Start off with Restful Web Services by Leonard Richardson and Sam Ruby. This book is fantastic from getting you from zero knowledge to "I know how Rails does REST by default," which is how most people do REST. But as you know, that's flawed. However, understanding this stuff is crucial, not only for when you interact with REST services, but also for understanding how Hypermedia APIs work differently. This baseline of knowledge is really important.
It also comes in cookbook form. You really only need one or the other; pick whichever format you like.
Next up, read REST in Practice: Hypermedia and Systems Architecture. This book serves as a great bridge to understanding Hypermedia APIs from the RESTful world. Chapters one through four read like Richardson & Ruby; yet they start slipping in the better hypermedia terminology. Chapter five really starts to dig into how Hypermedia APIs work, and is a great introduction. Chapter six covers scaling, chapter seven is an introduction to using ATOM for more than an RSS replacement, nine is about security, and eleven is a great comparison of how Hypermedia and WS-* APIs differ. All in all, a great intermediate book.
To really start to truly think in Hypermedia, though, you must read Building Hypermedia APIs with HTML5 and Node. Don't let the title fool you, as Mike says in the introduction:
[HTML5, Node.js, and CouchDB] are used as tools illustrating points about hypermedia design and implementation.
This is not a Node.js book. I find Node slightly distasteful, but all the examples were easy to follow, even without more than a cursory working knowledge.
Anyway, the book: Mike says something else that's really important in the intro:
While the subject of the REST architectural style comes up occasionally, this book does not explore the topic at all. It is true that REST identifies hypermedia as an important aspect of the style, but this is not the case for the inverse. Increasing attention to hypermedia designs can improve the quality and functionality of many styles of distributed network architecture including REST.
And, in the afterward:
However, the aim of this book was not to create a definitive work on designing hypermedia APIs. Instead, it was to identify helpful concepts, suggest useful methodologies, and provide pertinent examples that encourage architects, designers, and developers to see the value and utility of hypermedia in their own implementations.
I think these two statements, taken together, describe the book perfectly. The title is "Building Hypermedia APIs," not "Designing." So why recommend it on an API design list? Because understanding media types, and specifically hypermedia-enabled media types, is the key to understanding Hypermedia APIs. Hence the name.
Mike is a great guy who's personally helped me learn much of the things that I know about REST, and I'm very thankful to him for that. I can't recommend this book highly enough.
However, that may leave you wondering: Where's the definitive work on how to actually build and design a Hypermedia API? Did I mention, totally unrelated of course, that I'm writing a book? ;)
Yes, it still has REST in the title. Think about that for a while, I'm sure you can see towards my plans. I'm planning on a beta release as soon as I'm recovered from some surgery this week, but I'm not sure how long that will take, exactly. So keep your eyes peeled.

Books I won't recommend

REST API Design Rulebook , while I haven't actually read it, seems quite terrible. Let me copy an Amazon review:
The first chapters give a good feel for the vocabulary, and some good techniques for implementing REST. A lot of the 'rules', especially those related to basic CRUD operations, are clean and simple with useful examples.
Unfortunately, the later chapters get more and more focused on specifying something called 'WRML', which is a concept/language newly introduced in this book as far as I can tell.
Personally I would recommend ignoring the sections dealing with WRML (or keep them in mind as a detailed example of one possible way of handling some of the REST issues).
As to WRML itself: yuck. It appears to be an attempt to drag in some of the unnecessary complexity of SOAP with little added benefit. Not recommended.
Looking up information about WRML, I can agree, 100%. Ugh. So nasty. So this gets a big fat downvote from me.

Monday 5 March 2012

Rails 3.2.2 has been released!

Rails 3.2.2 has been released. This release contains various bug fixes and two important security fixes. All users are recommended to upgrade as soon as possible.

CHANGES

For information regarding the possible vulnerabilities, please see the announcements here and here.
Some highlights from this release are:
  • Log files are always flushed
  • Failing tests will exit with nonzero status code
  • Elimination of calls to deprecated methods
  • Query cache instrumentation includes bindings in the payload
  • Hidden checkbox values are not set if the value is nil
  • Various Ruby 2.0 compatibility fixes
For a comprehensive list, see the commits on github.