Saturday, January 31, 2009

How to add "Cross Sell" with rails

cross_sell products (Related products):

create table products :

CREATE TABLE products (
id INT NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
PRIMARY KEY (id)
);

Create a table 'cross_sell' in the mysql query browser :

CREATE TABLE cross_sells (
product_id INT NOT NULL,
cross_sell_product_id INT NOT NULL,
cs_position INT NOT NULL,
PRIMARY KEY (product_id, cross_sell_product_id),
UNIQUE KEY pos (cs_position)
);

steps to create a table in mysql query browser:

1. Right click on the database and select 'create table'.
2. Fill all the fields, all the columns and say apply. and execute.

In the model say 'product', type the following :
has_and_belongs_to_many :cross_sell_products,
:join_table => 'cross_sells',
:foreign_key => 'product_id',
:association_foreign_key => 'cross_sell_product_id',
:class_name => 'Product',
:order => 'cs_position'

In the show view of product :i.e in our example : /view/home/product.html.erb

Related Products :


<% @product.cross_sell_products.each do |cross_sell_product|%>
<%= link_to cross_sell_product.name, :action => 'product',
:id => cross_sell_product.id %>

<% end %>

Now fill in the table cross_sell, with product_id and its related product id, ie. cross_sell_id.

ActionWebService : Ruby on Rails

Installing the gem
$ sudo gem install datanoise-actionwebservice --source http://gems.github.com

Configuration

  1. Add this line to your config/environment.rb file in the initializer section:

    config.gem 'datanoise-actionwebservice', :lib => 'actionwebservice'
  2. Add this require statement to test/test_helper.rb file:

    require 'action_web_service/test_invoke'

Generating API controller

ActionWebService gem includes web_service generator that you can use like this:

$ ./script/generate web_service post
exists app/services/
exists app/controllers/
exists test/functional/
create app/services/post_api.rb
create app/controllers/post_controller.rb
create test/functional/post_api_test.rb

Note that your Apis are placed into app/services directory which Rails automatically includes in the search path, instead of the old app/apis directory.

Define your API

Open app/services/post_api.rb file and add methods that your service exposes:

class PostApi < ActionWebService::API::Base
api_method :get_posts, :returns => [[:string]]
end

Here, we defined get_posts method that accepts no parameters and returns an array of strings.

API implementation

We are going to use direct dispatching mode, so all methods that implement our API go directly to PostController itself:

class PostController < ApplicationController
wsdl_service_name 'Post'
web_service_api PostApi
web_service_scaffold :invocation if Rails.env == 'development'

def get_posts
["Post 1", "Post 2"]
end
end

Several things need to mention here:

  1. We use scaffolding in the development mode, so we can easily test our API via the browser. Just go to http://localhost:3000/post/invocation and follow the screens to make an API call.

  2. You can get WSDL of our Post API from http://localhost:3000/post/wsdl:

    $ curl http://localhost:3000/post/wsdl

    ...
  3. The URL that you actually use to make API calls is http://localhost:3000/post/api

Unit Testing

As you probably noticed, our web_service generator created a unit test file test/functional/post_api_test.rb. Lets test our get_posts method:

require File.dirname(__FILE__) + '/../test_helper'
require 'post_controller'

class PostController; def rescue_action(e) raise e end; end

class PostControllerApiTest < Test::Unit::TestCase
def setup
@controller = PostController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
end

def test_get_posts
result = invoke :get_posts
assert_equal(["Post 1", "Post 2"], result)
end
end

Lets see if it works:

$ ruby test/functional/post_api_test.rb
Loaded suite test/functional/post_api_test
Started
.
Finished in 0.182469 seconds.

1 tests, 1 assertions, 0 failures, 0 errors

Compiling Apache from source

Steps to compile apache:
step 1: get the source cd /home/hkorupol/software/
#tar -xvzf http*
#cd httpd *
#./configure --prefix=/usr/local/apache2 \
--enable-so --enable-modules=all \
--enable-mods-shared=all –enable-proxy
#make
#make install

About Me

Friendly and humanitarian Honest and loyal Original and inventive Independent and intellectual