Home

Seen on Stack Overflow E-mail
Saturday, 14 May 2011 14:44

The question was removed so I couldn't get the entire text, but I was able to capture the gist of it.

so



 
My explanation of REST (Representational State Transfer) E-mail
Sunday, 17 April 2011 12:01

There is a lot of information on the web about REST.  But I find much of it unclear, especially for someone without a background in how HTTP works and web application development.  I would like to provide my own (slightly verbose) definition of REST and also link to a handful of useful resources around the web on the subject.

 

My explanation

Background (source)

  1. First of all, REST is not a standard or any kind, it is a style of architecting web applications that aims to benefit from pre-existing features of the HTTP protocol, the protocol that essentially powers the Web.
  2. Under REST, "things" on the web that users are interested in and interact with are resources.  So on a blog site a particular blog post is a resource; a listing of all blog posts is also a resource.  On a shopping site any particular item is a resource, a listing by category is a resource, and so on.
  3. Users interact with resources in representations.  Again, for a blog site, viewing a blog post in a web browser is an HTML representation of that resource; viewing the blog post in an RSS reader is an XML representation of the same resource.
  4. Each interaction places the requesting client in a state, and each new interaction between the client (web browser, RSS reader, etc.) and server is a transfer that updates the state of the client.

What does it mean in practice?

An important thing to know:

  • Resources are represented by nouns.  That is, under a REST-ful application design, your URLs contain the identifier (ID, name, etc.) of the resource you are interacting with, and not some verb describing how you are interacting with that resource.

Let's say a resource is requested at a URL: http://www.somesite.com/blog/posts/a_blog_post

On its own the URL is ambiguous.  You may assume that a user is trying to view the blog post, but under REST, the same URL is used when you want to perform other operations on that resource, like edit or delete it.  So how does the application know what you are trying to do with the resource?  This is where HTTP comes in.

HTTP verbiage

HTTP has built into it four "verbs" that describe the type of interaction you are trying to perform.  If you're familiar with the common CRUD operations, this is how they map to those HTTP verbs:

 

CRUD Operation HTTP operation
Create POST
Read GET
Edit/Update PUT
Delete DELETE

 

So, here's the lesson: With every request sent to a server, two pieces of data are being transmitted:

  1. A noun - the identifier of the resource you are interested in
  2. A verb - an HTTP operation describing how you want to interact with that resource

The beauty of REST is that these descriptors being used are already present in the technologies that power the World Wide Web, so you're not inventing anything new, but simply taking advantage of something that's already there but for some reason has been overlooked.

Consequences

  1. Instead of a URL like http://www.somesite.com/blog/posts/?id=1234&action=edit you can have something like http://www.somesite.com/blog/posts/1234, and the application knows you are trying to edit (instead of view or delete, for example) because the HTTP header that gets sent along with the request tells it so.
  2. Additionally, that same URL can grab an XML (or JSON, or some other) version of the same blog post.  What I didn't mention above is that a third piece of data is being transmitted with your request: the format you want the response in.

Result

One clean and simple URL with many applications, thanks to protocols already built into the system.

The Art of Rails

One of the best explanations of REST is provided in Chapter 6 of the book The Art of Rails by Edward Benson.  Here are some worthy excerpts.

The Art of Rails

On representations

When I drive to work in the morning, I am using the physical representation of that resource. If I look at a photo of my car, I am looking at a graphical representation of that resource. When my transmission blew, the auto repair shop used their computers to pull up a repair-history representation of that resource. These are three different physical representations of the same conceptual entity, the resource.

On REST

Resource-oriented programming ... uses URLs to represent the resources contained within the system — the nouns — and makes the specification of actions to be performed on those resources secondary.

From the REST perspective, web applications are programs that observe and modify the states of those resources.

RESTful development suggests that developers return to using HTTP commands to specify the CRUD operation to be performed and to standardize on these commands as the common set of operations available for all resources contained within a web application.

The mandate that all RESTful resources be accessible by the same standard set of operations simplifies both API development and API use. Your web application API becomes the set of resource endpoints, and HTTP-based REST operations become the method calls into that API.

Other references



 
Ruby on Rails 3: Simple voting system with AJAX (with jQuery) E-mail
Tuesday, 12 April 2011 15:28

Introduction

You have a site based around a model - it could be blog posts, photos, videos, comments on any of those other models - and you want to add a simple voting feature where visitors can vote on a blog post, photo, or whatever else it might be.

 

There are plugins available for Rails to implement voting, thumbs_up being the most popular one for Rails 3, but it's not hard to create your own simple voting mechanism.

 

The one I'm going to demonstrate here will have the following features:

  • Item being voted on: item, item serving as the vote: vote (simple enough?)
  • Only one type of voting - the plugins allow for "for" and "against" votes, but I didn't need that in my project.  It wouldn't be too hard to modify this method to accommodate this.
  • Time-limited voting - a user can vote for any one "item" once every 24 hours.  For this to work your site needs a registration system, or some method that uniquely identifies users, so you can track who has voted on what and when.
  • Items will be sortable by votes
  • AJAX response - when a user votes the vote will be saved asynchronously and a response will be returned via AJAX.  I'll be using jQuery.
  • Administrators will not be creating, modifiying, or deleting votes manually

Requirements

In addition to what comes bundled with Rails, you will need:

You can now link to both these files with:

<%= javascript_include_tag 'http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.5.1.js', 'rails' %>

This code can go in your application.html.erb layout file so it's included everywhere in your application, or you can place it only in the files that need it, that will have something to do with the voting functionality you're adding.

Code generation

(I'm showing the final code here, but I'll break it down further on in the next step of the tutorial.)

At the command prompt execute:

rails g scaffold vote item_id:integer user_id:integer

If you haven't used Rails scaffolding before, this will generate the model, controller, views to execute CRUD operations, and related test files.  You won't need most of the functions and methods the scaffolding will generate, but it's quicker to delete what you don't need than to create what you need from scratch.

Create a column in your items table to store a votes_count integer value

rails g migration add_votes_to_items votes_count:integer

This will run both the scaffold-generated migration for vote and the one you just generated for item

rake db:migrate

 
 
class Item < ActiveRecord::Base
 
    has_many :votes
 
 

Delete all files under views/votes, we won't be needing them, and trim your model and controller to look like the following:

vote.rb

 
 
class Vote < ActiveRecord::Base
  belongs_to :item, :counter_cache => true
 
# rest of your code here
end
 
 

votes_controller.rb

Copy this code to a text file or somewhere else where you can reference it as you read the explanation that follows.

In the views/votes folder that you just emptied, create a create.js.erb file.  This is the response that will be returned by the votes' controller's create action after a vote has been successfully created.

 
 
$(document).ready(function(){
 
    alert('This is a pathetically simple AJAX response!');
 
});
 
 

All you need is a simple button that allows a user to vote for an item in, for example, the items index and item show views.  The form should have hidden fields for the two values you need to store,  item_id and user_id.  Notice the :remote => true in the form_for tag.

 
 
<%= form_for(@vote, :remote => true) do |f| %>
<%= f.hidden_field "item_id", :value => item.id %>
<%= f.hidden_field "user_id", :value => @user.id %>
<%= image_submit_tag "buttons/vote-for-item.png" %>
<% end %>
 
 

You also need to add a line to the corresponding actions in items_controller.rb.  If you don't add this you'll get an error when you go to pull up your views.

 
 
def index
 
    @vote = Vote.new(params[:vote])
 
    #rest of your code here
 
end
 
 

 
 
def show
 
    @vote = Vote.new(params[:vote])
 
    #rest of your code here
 
 

Explanation

I'll break this down by file:

 
 
class Vote < ActiveRecord::Base
  belongs_to :item, :counter_cache => true
 
# rest of your code here
end
 
 

  • belongs_to you should already know by now.  It creates a one-to-many relationship between item and vote (with has_many :votes in item.rb)
  • counter_cache is a great feature of Rails that keeps track of the "count" of votes an item has in the additional votes_count column we added to the items table.  So if later you want to sort items by votes, you can do something like:

 
 
@items = Item.order("votes_count DESC")
 
 

Lines 18-24, 34-36

These lines set up the check for whether the current user (line 19) has voted for the current item (line 18) within the last 24 hours (line 24).  If not, the vote is saved, otherwise the user is alerted (line 35) that they cannot vote again just yet.

Line 27

This line is required for the AJAX response.  This tells the controller that this action can return a JavaScript response in addition to the HTML response that's there by default.  The create.js.erb will now be rendered because we've told the controller to respond to JS requests and we've named the view the same as the controller action.

The key here is the :remote => true, which enables the AJAX functionality of this simple form.

And that's it!  Your AJAX'ed voting system is ready!



 
On professionalism E-mail
Saturday, 26 February 2011 12:08

Recently, for work on a client's site, I had to contact a representative at a company whose service I had to integrate into the client's site.  Here's my e-mail to the representative:

Hi Mr. P-,
My name is Pranshu Arya, I am developing a website for a group of --- who have subscribed to your --- services.  I was wondering if you would be able to answer a few technical questions for me about the service you provide.

In his infinite wisdom this douchebag decided to forward me the message from his technical person, including what he wrote to that person.  The response I received from this person was (interesting part in bold):

Hey Pranshu…
Here are your answers: Please see below.
On Thu, Feb 3, 2011 at 1:40 PM, C  P wrote:
Hey… do you mind answering these quickly for me to talk to this guy later?
It is not worth wasting time on a call with him just yet but I want him to be able to see that it is an easy back end solution so he gives the thumbs up to the money guy…

That was the first e-mail.  After that I had to send a second, asking technical questions, and the response came:

On Wed, Feb 9, 2011 at 6:53 PM, C P wrote:
We got a signed contract back today from these guys so I guess they are worth the time

Is it just me or is this extremely unprofessional behavior from someone who considers themselves a "professional" and represents the public face of a company?



 
Rails 3 error: 'require': no such file to load -- readline (LoadError) E-mail
Monday, 07 February 2011 21:38

If you get an error like this trying to run rails console in a Rails 3 project:

`require': no such file to load -- readline (LoadError)

In Ubuntu you need to run the following (see here for other platforms):

sudo apt-get install libncurses5-dev libreadline5-dev

Then locate your current Ruby installation.  Mine, for example, is under /home/pranshu/.rvm/gems/ruby-1.9.2-p0 because I'm using RVM to manage multiple Ruby versions.

 

Run:

cd /home/pranshu/.rvm/gems/ruby-1.9.2-p0/ext/readline
ruby extconf.rb
make
make install

Next time you try running rails console it should run fine.



Tags: Ruby on Rails  Rails 3  Ruby  Linux  make  Ubuntu  
 
Installing Authlogic in Rails 3 E-mail
Monday, 24 January 2011 16:52

The authlogic gem/plugin seems to be the most popular authentication extension for Rails right now.  It comes with some good tutorials, but they're not up to date for Rails 3, so I culled the following steps from various sources to get it to work with Rails 3.  (Here is the official tutorial.)

 

My implementation is:

  1. Name (name) and e-mail (email) are required fields
  2. E-mail serves as the login username
  3. User paths are placed behind '/admin' prefix, with an admin controller and index view for convenience
  4. Users are managed by the user model and users controller, and user sessions by the user_sessions controller (there is a user_session model but it's empty).

Here are the steps to follow:

  1. In your Gemfile, add the following (and afterwards run bundle install):
  2. gem 'authlogic'

  3. Generate models:
  4. rails g authlogic:session user_session
     
    rails g model user

  5. Generate controllers:
  6. rails g controller user_sessions
     
    rails g controller users
     
    rails g controller admin

  7. Add fields to create_user model migration.  This is what mine looked like:
  8. class CreateUsers < ActiveRecord::Migration
      def self.up
        create_table :users do |t|
          t.string    :name,                :null => false
          t.string    :email,               :null => false, :length => 320
     
          t.string    :crypted_password,    :null => false
          t.string    :password_salt,       :null => false
          t.string    :persistence_token,   :null => false
     
          # Magic columns, just like ActiveRecord's created_at and updated_at.
          # These are automatically maintained by Authlogic if they are present.
          t.integer   :login_count,         :null => false, :default => 0
          t.integer   :failed_login_count:null => false, :default => 0
          t.datetime  :last_request_at
          t.datetime  :current_login_at
          t.datetime  :last_login_at
          t.string    :current_login_ip
          t.string    :last_login_ip
     
          t.timestamps
        end
        add_index :users, :email
      end
     
      def self.down
        remove_index :users, :email
        drop_table :users
      end
    end

  9. Create a create_user_sessions migration:
  10. class CreateUserSessions < ActiveRecord::Migration
      def self.up
        create_table :user_sessions do |t|
     
          t.timestamps
        end
      end
     
      def self.down
        drop_table :user_sessions
      end
    end

The contents of the various files are:

Models

class User < ActiveRecord::Base
    acts_as_authentic
    validates :name, :email, :presence => true
    validates :email, :uniqueness => true
 
end

Controllers

class AdminController < ApplicationController
 
  before_filter :require_user  
 
   def index
 
   end
 
 end

Views

<%= form.label :name %><br />
 
<%= form.text_field :name %><br />
 
<br />
 
<%= form.label :email %><br />
 
<%= form.text_field :email %><br />
 
<br />
 
<%= form.label :password, form.object.new_record? ? nil : "Change password" %><br />
 
<%= form.password_field :password %><br />
 
<br />
 
<%= form.label :password_confirmation %><br />
 
<%= form.password_field :password_confirmation %><br />

<h1>Register</h1>
 
<% form_for @user, :url => users_path do |f| %>
 
  <%= render :partial => "form", :object => f %><br />
 
  <%= f.submit "Register" %>
 
<% end %>

<h1>Edit user</h1>
 
<% form_for @user, :url => user_path do |f| %>
 
  <%= render :partial => "form", :object => f %>
 
  <%= f.submit "Update" %>
 
<% end %>
<br /><%= link_to "View user", user_path %>

<p>
 
  <b>Name:</b>
 
  <%=h @user.name %>
 
</p>
 
<p>
 
  <b>E-mail:</b>
 
  <%=h @user.email %>
 
</p>
<p>
 
  <b>Login count:</b>
 
  <%=h @user.login_count %>
 
</p>
<p>
 
  <b>Last request at:</b>
 
  <%=h @user.last_request_at %>
 
</p>
<p>
 
  <b>Last login at:</b>
 
  <%=h @user.last_login_at %>
 
</p>
<p>
 
  <b>Current login at:</b>
 
  <%=h @user.current_login_at %>
 
</p>
<p>
 
  <b>Last login ip:</b>
 
  <%=h @user.last_login_ip %>
 
</p>
<p>
 
  <b>Current login ip:</b>
 
  <%=h @user.current_login_ip %>
 
</p>
 
<%= link_to 'Edit', edit_user_path %>

<h1>Login</h1>
 
<% form_for @user_session, :url => sign_in_path do |f| %>
 
  <%= f.label :email %><br />
 
  <%= f.text_field :email %><br />
 
  <br />
 
  <%= f.label :password %><br />
 
  <%= f.password_field :password %><br />
 
  <br />
 
  <%= f.check_box :remember_me %>
 
<%= f.label :remember_me %><br />
 
  <br />
 
  <%= f.submit "Login" %>
 
<% end %>

<h1>Admin panel</h1>
 
<%= link_to "Users", users_path %><br />

Routes.rb

#for users
 
scope :path => '/admin' do
 
    resources :users #places all the "users" links behind /admin URL prefix
 
 end
 
#for user_sessions
 
match "/admin"    => "admin#index"
 
get   "sign_in"   => "user_sessions#new"
 
post  "sign_in"   => "user_sessions#create"
 
match "sign_out"  => "user_sessions#destroy"



 
Using Akamai's Content Control Utility SOAP API E-mail
Tuesday, 28 December 2010 12:24

Akamai's Content Control Utility (CCU) SOAP API has a malformed WSDL (at https://ccuapi.akamai.com/ccuapi-axis.wsdl).  Here is what soapUI shows:

ccuapi-1

 

Here, on the other hand, is the properly formatted SOAP envelope that works:

<?xml version="1.0" encoding="UTF-8"?> 
        <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
 
xmlns:ns1="http://www.akamai.com/purge"
 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
 
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
          <SOAP-ENV:Body>
            <ns1:purgeRequest>
              <name xsi:type="xsd:string">uname</name>
              <pwd xsi:type="xsd:string">passwd</pwd>
              <network xsi:type="xsd:string"></network>
              <opt SOAP-ENC:arrayType="xsd:string[0]" xsi:type="ns1:ArrayOfString">
                <item xsi:type="xsd:string">action=remove</item>
                <item xsi:type="xsd:string">type=arl</item>
              </opt>
              <uri SOAP-ENC:arrayType="xsd:string[1]" xsi:type="ns1:ArrayOfString">
                <item xsi:type="xsd:string">' + url + '</item>
              </uri>
            </ns1:purgeRequest>
          </SOAP-ENV:Body>
        </SOAP-ENV:Envelope>

See the differences?

Below is an implementation of it in Rails using the Savon gem:

The check_urlink function:

def check_urlink(urlink)
urlink = "http://" + urlink unless (urlink.blank? or urlink.starts_with?("http://"))    
end



 
«StartPrev12345678910NextEnd»

Page 3 of 18