Subhashmohan's Blog

This post is to give a brief introduction of what’s new in rails 4.0

Strong Parameters

Mass assignment restriction has been moved from model to controller level. Ealier we used attr_accessible and attr_protected methods in model for mass assignment security, These are been removed and moved to the protected_attributes gem.

In the new implementation, passing params directly to the mass assignment methods like create will raise a ActiveModel::ForbiddenAttributesError, instead of passing params directly to the create method in the controller, we pass a private method which permits the accessible attributes.

class PeopleController < ActionController::Base
   # Using “Person.create(params[:person])” would raise an
   # ActiveModel::ForbiddenAttributes exception because it’d
   # be using mass assignment without an explicit permit step.
   # This is the recommended form:
   def create
     Person.create(person_params)
   end

  # This will pass with flying colors as long as there’s a person key in the
  # parameters, otherwise it’ll raise an ActionController::MissingParameter
  # exception, which will get caught by ActionController::Base and turned
  # into a 400 Bad Request reply.
  def update
    redirect_to current_account.people.find(params[:id]).tap { |person|
    person.update!(person_params)
   }
  end

  private
  # Using a private method to encapsulate the permissible parameters is
  # just a good pattern since you’ll be able to reuse the same permit
  # list between create and update. Also, you can specialize this method
  # with per-user checking of permissible attributes.
  def person_params
    params.require(:person).permit(:name, :age)
  end
end

Turbolinks

Turbolinks is a gem that is included by default in rails 4.0. This gem make your application feel faster to the user using javascript (i.e AJAX Request) to replace the html body of new pages instead of relying on full page load with which the browser don’t have to reparse your js or css on every page load.

Russian Doll Caching

Russian Doll Caching is a mechanism of using nested fragment caches to have maximum cache hits to boost up the performance.

For example: If we have parent fragment and many child fragments under it, Changing the parent fragment will expire only the parent fragment and the child fragments will be still served from the cache. If the child fragment is changed the changed child fragment and its parent fragment will be expired.

One main advantage is cache_digests gem is included by default in rails 4.0 which avoids the use of version in fragment caching and instead generate a MD5 hash key based on the template content, which means if the template content changes the cache gets expired.

ActionController::Live

Live is a special module included in ActionController class. It enables Rails to open and close a stream explicitly. Mix this module in to your controller, and all actions in that controller will be able to stream data to the client as it’s written.

PATCH

The HTTP method PUT means resource creation or replacement at some given URL. For example say you have uploaded a file and you want to replace that with a new file that’s where PUT comes in to picture. As per http standards PUT is not for partial updates. PATCH is the new http verb added in rails 4.0 for partial updates

When you call id on nil object

Earlier i.e before ruby 1.9.3 when you call id on nil a weird error message was displayed ‘Called id for nil which would  mistakenly be 4. If you really want id of nil use object_id. This is because earlier calling id on any object would return the object_id, but this is not the case any more in ruby 1.9.3 and above. To get the object_id you need to explicitly call the object_id method on object. Hence the new error message when you attempt to call id on nil object is undefined method id for nil class.

Extraction of features to gems

  • Hash-based & Dynamic finder methods

  • Mass assignment protection in Active Record models

  • ActiveRecord::SessionStore

  • Active Record Observers

  • Active Resource

  • Action Caching

  • Page Caching

  • Sprockets

  • Performance tests
Advertisements

Suppose you have a field in your table, which accepts array of values through multiple checkboxes, then here is a way to show these checkboxes on your active scaffold create/update form.

#Controller

class UsersController < ApplicationController
active_scaffold :user do |config|
config.label = “Users”
config.columns = [:name,  :gender, :checklist ]
config.columns[:gender].form_ui = :radio
config.columns[:gender].options[:options] = [[‘Male’, ‘1’], [‘Female’,’2′]]
end
end

Assume ‘checklist’ is the column which accepts an array of values, then add the below chunk of code to your users helper

#Users helper

module UsersHelper
def checklist_form_column(record, options)
html = ‘ ‘
(1..5).each do |val|
html << check_box_tag(“record[checklist][]”, val, :id => “check_#{val}”)
html << “<label for=’check_#{val}’>”
html << “lable_#{val}”
html << “</label>”
html << “<br/>”
end
html
end
end

The way to add radio buttons to your active scaffold create/update from is as shown below

#Controller

class UsersController < ApplicationController
active_scaffold :user do |config|
config.label = “Users”
config.columns = [:name, :gender]
config.columns[:gender].form_ui = :radio
config.columns[:gender].options[:options] = [[‘Male’, ‘1’], [‘Female’,’2′]]
end
end

Installation

1. Follow this link to download and install memcached.
2. Start the memcached server using either

memcached -vv

or

/etc/init.d/memcached start

Integrating memcached with your rails application.

1. Install memcache-client

gem install memcache-client

2. Add the below line to  end of your config/environment.rb file.

CACHE = MemCache.new('127.0.0.1')

3. Add the following method to your application controller / application helper or where ever you want according to your need.

def perform_cache(key)
  begin
   unless output = CACHE.get(key)
     output = yield
     CACHE.set(key, output, 15.minutes)
   end
 rescue => e
  logger.info “MEMCACHE ERROR++++++++++++++++++++++++++++++++++++”
  logger.info “ERROR : #{e.message}”
  logger.info “MEMCACHE ERROR++++++++++++++++++++++++++++++++++++”
  output = yield
  end
  return output
 end

The above method performs the caching based on a unique key. If the value for that key already exists, it will return the output from the stored cache or  else it will execute the block you are using when calling the above method and generate a new value from the executed block for the particular key and store it in the cache.

You can set a timer to expire the cached data.(15 mins in my case.)

If you don’t want to expire the cache based on timer, simply remove the third parameter we are passing to ’set’ method.

The above method also handles the exception,in case your memcache server is down for some reason.

4.  Cache your complex queries/methods as follows.

my_key =  Digest::MD5.hexdigest(request.request_uri)
output = perform_cache(my_key) { ClassName.method_name(…) }

Note : The key generated should be always unique, otherwise it will overwrite your existing cached data already having the same key. I am using the URL as the key, Since the URL is pretty long we can take the MD5 hash/SHA1 hash of it and use it as the key.

5.  You can edit memory  used by memcached as follows.

Open /etc/sysconfig/memcached file and edit “CACHESIZE” entry,
this entry is in MBs.

That's it your ready to go.

Introduction

gem “whenever“  provides you with the valid cronjob syntax and also writes / updates the crontab file for you.

Installation

1.  Install the gem

gem install whenever

2. Add below line to your config/environment.rb

config.gem ‘whenever’, :lib=>false, :source=>’http://gemcutter.org&#8217;

3.  Go to your application root directory and run the below command

wheneverize .

   This will create a “config/schedule.rb” file for you.

  EXAMPLE “config/schedule.rb”

  set :environment, :development

  set :path, "/var/www/MyApp"

  # Scheduled Hourly

   every 4.hours do
   command "/usr/bin/your_command"
   end

  # Scheduled Daily

   every 1.day, :at => '12:00 am' do
   runner "MyModel.yourmethod"
   end

   # Scheduled Weekly

   every :monday, :at => '11:00 pm' do
   rake   "your:rake:task"
   end

Consider the above as the contents of your config/schedule.rb file.

4.  Now from application root directory, run the below command

whenever

The above command will output valid syntax for the crontab as below.

 0 0 * * * /var/www/MyApp/script/runner -e development “Model.your_method”

 0 0,4,8,12,16,20 * * * /usr/bin/your_command

 0 23 * * 1 cd /var/www/MyApp && RAILS_ENV=development /usr/bin/env rake your:rake_task
 

5. Now, To write the above content in your Crontab file run the below command.

whenever –update-crontab

you can see the above entries in your crontab file by running “crontab -e”.

That’s it, you are ready to go.

 




Before you get to know how to install and use Edge Rails, you need to know what actually Edge Rails is.

Edge Rails actually means running a local developmental version of rails. It’s an alternative to gem rails.

Many a times I have thought how to freeze my rails application to local gems version or a particular gems version, So that I can run my frozen application on some other system which have some different version of rails installed. Luckily I found Edge Rails.

For example:- Consider you have frozen your rails application to the latest rails version 2.3.2 and you want to run this application on a different system which have a much older version of rails, consider for example version 2.1.0.

In this case you can run your newest frozen version of rails application on  other system, which have an older version of rails installed, without any glitches or bugs, using Edge Rails.

How to Install and Use Edge Rails?

1.  If you want to freeze your application to the gems version currently available on your system, then go to root of your rails application and run

rake rails:freeze:gems

By running the above command a new directory “rails” will be created inside your vendors directory. When you run your rails framework, Your application will first check for this directory and if it’s present, Rails components will be loaded from this directory instead of using your system copy of rails, and thus you are switched from Gems Rails to Edge Rails.

2.  If at any point of time, you want to switch back from Edge Rails to Gem Rails. You can always do it by running the below command

rake rails:unfreeze

3. If you want to freeze your application to the latest development version, then run.

rake rails:freeze:edge

once you are switched to the latest development version, your javascripts and other configuration files needs to be updated corresponding to the latest version. For this you need to run,

rake rails:update

4. Freeze your application to a different version.
Consider you want to freeze your rails application to rails version 2.1.0, then you have to just run the command

rake rails:freeze:edge RELEASE=2.1.0

5. In order to find out what version of rails your application uses, From the  root of your rails application, run

script/about

your output will be something like below.

About your application’s environment
Ruby version              1.8.6 (i686-linux)
RubyGems version          1.1.1
Rails version             2.1.0
Active Record version     2.1.0
Action Pack version       2.1.0
Active Resource version   2.1.0
Action Mailer version     2.1.0
Active Support version    2.1.0
Edge Rails revision       unknown
Application root          your application path
Environment               development
Database adapter          mysql
Database schema version   20090622125330
Loaded suite script/about
Started

Finished in 0.000606 seconds.

0 tests, 0 assertions, 0 failures, 0 errors

6. Installing all other application depending gems locally.

1. Consider your application require the following two gems

a) will_paginate
b) mini_magick

Now go to your config/environment.rb file and config the required gems  as  below.

Rails::Initializer.run do |config|
config.gem “mini_magick”
config.gem “will_paginate”
end

2. Now consider these gems are not yet installed in your local machine. In order to install the above gems in your local machine,  from the root of your application run

rake gems:install

If you have already installed the above gems at some point of time, then skip this step and proceed to next step.

3. Now In order to make the above gems application-dependent rather than system-dependent gems. You need to unpack all these gems inside your application using

rake gems:unpack

The above command will create a new directory “gems” inside your vendor folder and unpack the two gems “will_paginate” and “mini_magick” inside the “gems” directory.

4. Unpack gems individually

There are two ways to unpack the gems individually.

Either run this from the root of your application.

rake gems:unpack GEM=will_paginate

or

change your directory to /vendor/gems and run

gem unpack “gem_name”

4. Freeze your application to a different version.Consider you want to freeze your rails application to rails version 2.1.0, then you have to just run the command

Every one in the Ruby / Rails world knows and implements different payment methodologies for their E-commerce shopping cart. We understand people know much about how to integrate with Paypal, Authorize.net…blah blah blah… however the biggest issue with all these payment gateways is that the customers have to be associated with multiple websites i.e. If I want to buy something from a cart which associates to Paypal gateway, I need to have an account. So if that is the case then for every different Ecommerce payment gateway I need to have a separate account and I need to remember the credentials. Also many times if I want to implement offline payments such as money orders or cheque, etc., we don’t have any implementation that could take care of this system.

However many time I wished that it would be good that these shopping companies support multiple payment gateways and also multiple methods which are country oriented. E.g. Paypal is not an acceptable method in India, where as it is a Hit in US… Same way In France JCB is well known and in UK, Diners club, switch, maestro cards are well known. So I always believe that I should be allowed to pick up only the ones I need to make the payments as most of the time I shall be associated to one of them rather than getting myself associated to every one and forget at the end of the day where what transaction took place.

Thankfully to my support came in Bibit, a payment service of Royal Bank of Scotland (RBS) which supports almost all the payment gateways available and provides you information of gateways based on the country of the shopper. And to my advantage, I was supposed to write a code for a shopping cart to which it supported. Bibit is very much well known in Europe. Bibit also support Multi-Lingual

Before I start telling you how to implement bibit, a small introduction about BIBIT

“The Bibit Redirect, or Select, service model is an integration method to the Bibit Payment Service suited for Internet shop environments, call centers or reservation centers, and multi-channel sales situations. It allows for real-time processing of payments and ensures a maximum number of up-to-date payment methods. The Redirect model is secure, provides Bibit with required information to perform active fraud risk assessment, and is the fastest way to get up and running with on-line payments.” – As available in bibit website.

More details can be found in http://www.bibit.com . Also this post picks up much of the information from the bibit document and has been modified to suit Ruby on Rails users.

What bibit does is, it provides a standard methodology to the shopping cart websites who can register with Bibit and then run their code with bibit. Once the shopping websites provide bibit some information the control is transferred to Bibit and after completion just like paypal, you can take back the control.  So actually the shopping Cart websites integrate their systems with bibit and bibit provides the customers of the shopping cart websites with various predefined payment gateways based on the country and languages.

Now we know what Bibit is, Lets to see how we can integrate bibit to our shopping carts.

Bibit provides an exclusive method called XML Order Creation which can be utilized to send information to bibit’s website as a secured channel and they handle the rest. The data is sent as an XML with some key elements such as description, amount, orderContent, paymentMethodMask and shopper.

Some of the Elements of this XML are as follows

1. Document Type Declarations

As with any XML declaration we need to declare bibit as well to use the standards payment service dtd as follows

<?xml version=”1.0″?>

<!DOCTYPE paymentService PUBLIC “-//Bibit//DTD Bibit PaymentService v1//EN”

“http://dtd.bibit.com/paymentService_v1.dtd”>

2. Merchant Information

This is the information that the shopping cart have to provide to bibit in order to authorize the input XML. The main information required is the merchant code.

<paymentService version=”1.4″ merchantCode=”MYMERCHANTCODE”>

<submit>

</submit>

</paymentService>

The XML requires only the Merchant code, however in order to send the xml to the bibit website we need the merchant code as login and the xml password to send this XML. This is more explained in the Http Connectivity section

3.  Order Creation Details

While creating an order we have to follow few significant methods so that Bibit understands the order that has been sent. Some of them are

a.  Order Description – Requires Order Code, Description, Order value, Currency in which order is being placed and the decimal place. The below is a sample example of an order. The Order Code has to be very much unique from bibit’s perspective and hence it is advisable to create the ordercode with a Salt of your’s and a number

<order orderCode=”T0211011″>

<description>Some description of your product</description>

<amount value=”2600″ currencyCode=”USD” exponent=”2″/>

</order>

b.  Order Content – Has the complete details of the order and its line items. These details are wrapped inside a CDATA to allow bibit to confirm / show the user the order details. This is something like giving the details of what you would ideally put in a Confirm page before you place the order.

<orderContent>

<![CDATA[content here]]>

</orderContent>

Some of the information that is generally part of order content are order code, line items, item price, total amount, shipping and billing addresses, merchant contact details, etc., For more information you can refer to bibit’s documentation.

c.  Selecting Payment Gateways – In bibit, you can select which all payment gateways that you can allow to your client to login and support.

<paymentMethodMask>

<include code=”ALL”/>

<include code=”VISA-SSL”/>

<exclude code=”AMEX-SSL”/>

</paymentMethodMask>

d.  Email address – Finally we need to give the shopper’s email address as follows

<shopper>

<shopperEmailAddress>shopper@myshopper.com</shopperEmailAddress>

</shopper>

4.  XML Validation

Finally it is a good practice to have a XML validation done on your xml. Bibit is quite strict about xml format and the transaction might fail for this activity.

So once you have the XML ready, it should look as below

<?xml version=”1.0″?>

<!DOCTYPE paymentService PUBLIC “-//Bibit/DTD Bibit PaymentService v1//EN”

“http://dtd.bibit.com/paymentService_v1.dtd”>

<paymentService version=”1.4″ merchantCode=”MYMERCHANT”>

<submit>

<order orderCode=”T0211011″>

<description>20 tulip bulbs from MYMERCHANT Webshops</description>

<amount value=”2600″ currencyCode=”EUR” exponent=”2″/>

<orderContent>

<![CDATA[

<center><table>

<tr><td bgcolor=”#ffff00″>Your Internet Order:</td><td colspan=”2″

bgcolor=”#ffff00″ align=”right”>T0211011</td></tr>

<tr><td bgcolor=”#ffff00″>Description:</td><td>20 Tulip bulbs</td><td

align=”right”>1,00</td></tr>

<tr><td colspan=”2″>Subtotal:</td><td align=”right”>20,00</td></tr>

<tr><td colspan=”2″>VAT: 15%</td><td align=”right”>3,00</td></tr>

<tr><td colspan=”2″>Shipping and Handling:</td><td align=”right”>3,00</td></tr>

<tr><td colspan=”2″ bgcolor=”#c0c0c0″>Total cost:</td><td bgcolor=”#c0c0c0″

align=”right”>Euro 26,00</td></tr>

<tr><td colspan=”3″>&nbsp;</td></tr>

<tr><td bgcolor=”#ffff00″ colspan=”3″>Your billing address:</td></tr>

<tr><td colspan=”3″>Mr. J. Shopper,<br>11 Shopperstreet,<br>1234

Shoppercity,<br>Netherlands</td></tr>

<tr><td colspan=”3″>&nbsp;</td></tr>

<tr><td bgcolor=”#ffff00″ colspan=”3″>Your shipping address:</td></tr>

<tr><td colspan=”3″>Mr.J. Shopper,<br>11 Shopperstreet,<br>1234

Shoppercity,<br>Netherlands</td></tr>

<tr><td colspan=”3″>&nbsp;</td></tr>

<tr><td bgcolor=”#ffff00″ colspan=”3″>Our contact information:</td></tr>

<tr><td colspan=”3″>MYMERCHANT Webshops International,<br>461 Merchant

Street,<br>1255 Merchanttown,<br>Netherlands

<br><br>mymerchant@webshops.int<br>(111) 1235 456</td></tr>

<tr><td colspan=”3″>&nbsp;</td></tr>

<tr><td bgcolor=”#c0c0c0″ colspan=”3″>Billing notice:</td></tr>

<tr><td colspan=”3″>Your payment will be handled by Bibit Global Payments

Services<br>This name may appear on your bank

statement<br>http://www.bibit.com</td></tr&gt;

</table></center>

]]>

</orderContent>

<paymentMethodMask>

<include code=”VISA-SSL”/>

<include code=”AMEX-SSL”/>

<include code=”ECMC-SSL”/>

</paymentMethodMask>

<shopper>

<shopperEmailAddress>jshopper@myprovider.int</shopperEmailAddress>

</shopper>

<shippingAddress>

<address>

<firstName>John</firstName>

<lastName>Shopper</lastName>

<street>11 Shopperstreet</street>

<postalCode>1234</postalCode>

<city>Shoppercity</city>

<countryCode>NL</countryCode>

<telephoneNumber>0123456789</telephoneNumber>

</address>

</shippingAddress>

</order>

</submit>

</paymentService>

What Next, now lets do some Ruby coding to send this XML to bibit and do the processing. We shall utilize Net HTTP for the same. So in your controller i.e. where you have checkout processing being done you can add this code. I shall call my controller as CartController and the code shall be in cart_controller.rb

The first thing I require is to declare the required lib files. We need to declare http, https and uri classes. These are available as follows

require ‘net/https’

require ‘net/http’

require ‘uri’

Once you have your declaration ready all you have to do is write the code in the make_payment  method

def make_payment

#….write all the necessary code.to do necessary bibit payments
end

Lets understand one by one on what has to be filled with in the make_payment method

First get the XML ready

xml_string = %{xml as above}

It is better to putin the xml with in the %{} as the content becomes a well formatted xml. If we try to do it as quotes or double quotes, lots of escape sequences have to be used which is a pain. We found out sing %{} is the best method.

Once your XML is ready, Start posting the XML throught NET HTTP

All you need for this to work, is connection to the bibit service, your merchant code and the merchant password that you have declared in bibit.com using your login credentials.

url = URI.parse(”https://secure-test.bibit.com/jsp/merchant/xml/paymentService.jsp”)

@http=Net::HTTP.new(url.host, url.port)

@http.use_ssl = true

@http.start(){|http|

req = Net::HTTP::Post.new(url.path)

req.basic_auth MYMERCHANTCODE, MYXMLPASSWORD

req[‘Content-Type’] = ‘text/xml’

req.body = xml_string # as seen above

response = http.request(req)

response_xml = response.body

return response_xml

}

The URL you see is for the bibit’s test environment, All you have to do is to change the url to https://secure-test.bibit.com/jsp/merchant/xml/paymentService.jsp.

Handling the Response

Once you send the XML to the bibit as above, bibit shall send you back an response XML which gives you some information about bibit accepting your order. All we have to do is to extract the order code and the re-direction information from response xml and re-direct our application to bibit to do the complete gateway process

<?xml version=”1.0″?>

<!DOCTYPE paymentService PUBLIC “-//Bibit//DTD Bibit PaymentService v1//EN”

“http://dtd.bibit.com/paymentService_v1.dtd”>

<paymentService merchantCode=”MYMERCHANTCODE” version=”1.4″>

<reply>

<orderStatus orderCode=”T0211011″>

<reference id=”1234567″>

https://secure-test.bibit.com/jsp/shopper/SelectPaymentMethod.jsp?orderKey=

MYMERCHANT^T0211011

</reference>

</orderStatus>

</reply>

</paymentService>

All that is important in this xml is

Order URL – This is the URL that has to be redirected to allow bibit to complete the payments. The url in the xml is

https://secure.bibit.com/jsp/shoppe/SelectPaymentMethod.jsp?orderKey=

MYMERCHANT^T0211011

Reference ID – This ID is more necessary for Future references or offline payments so that you know the status of the product. The reference ID in this xml response is

1234567

Order Code – This is the code that we generated before sending it to the bibit payment. This has to be unique and can be used to check in the database for order  placement. The order code in the xml response is

T0211011

In order to extract the information from the response xml we can use any parser such as ReXML parser / Atom Parser / CobraVsMongoose

Redirecting to Bibit

Once the URL has been acquired from the response XML, do a redirection to Bibit. Also you can do additional activities so that you can change the look and feel and information in the website.

a. Redirecting URLs

Additionally you can customize the URL to send your success / failure / pending URLs to Bibit to redirect to your website so that you can handle the particular order status i.e. When the Bibit completes the payment and if you want them to redirect back to your website (similar to returnurl of paypal), you can provide them as encoded text along with the bibit url (available in the response xml). The procedure could be as follows

&successURL=CGI::escape(url_for(:controller=>”cart”, :action=>”success”)

&pendingURL=CGI::escape(url_for(:controller=>”cart”, :action=>”pending”)

&failureURL=CGI::escape(url_for(:controller=>”cart”, :action=>”failure”)

https://secure.bibit.com/jsp/shopper/SelectPaymentMethod.jsp?orderKey=MYMERCHANTCODE^T0211011&successURL=http%3A%2F%2Fyour_domain.com%2Fcart%2Fsuccess&failureURL=http%3A%2F%2Fyour_domain.com%2Fcart%2Ffailure&pendingURL=http%3A%2F%2Fyour_domain.com%2Fcart%2Fpending

You are at your disposable to implement any of these. Bibit shall redirect to your URLs along with the order code so that you can handle if you want to convert the cart into an order or not. A sample Success URL that bibit creates is as follows

http://www.your_domain.com/cart/success?orderKey=MYADMINCODE^MYMERCHANTCODE^T0211010&paymentStatus=AUTHORISED&paymentAmount=2600&paymentCurrency=USD&mac=0083c47880f0533d773c350ee0d51cfc

b. Setting Country and Language Codes

You can also set bibit the country code and the language code in order to allow bibit to show the payment methodologies for particular country and the bibit originating text based on language. This is again sent as part of the bibit url. Example URL is as follows
https://secure.bibit.com/jsp/shopper/SelectPaymentMethod.jsp?orderKey=MYMERCHANTCODE^T0211011&country=GB&language=en

c. Setting User Interface of Bibit Payment Service

You can also send font / body attributes to allow bibit show information in the way you want. E.g.

https://secure.bibit.com/jsp/shopper/SelectPaymentMethod.jsp?orderKey=MYMERCHANTCODE^T0211011&bodyAttr=bgcolor%3D%22black%22&fontAttr=face%3D%22arial%22+color%3D%22white%2

Hope this information helps you to start understanding and handle payments for your websites. We say three cheers to Bibit to help us solve a big problem.

Let me know your comments or if you need any support implementing Bibit Payments for your website.

Blog Stats

  • 3,807 hits
November 2017
M T W T F S S
« Mar    
 12345
6789101112
13141516171819
20212223242526
27282930  

Categories

Pages