Let us say we have an invoice management system. When an invoice is approved, the system creates a payment directive.
Upon successfully creating the payment directive, the system requests a 3rd party gateway to schedule a payment to the invoiced vendor.
Upon successful scheduling the payment, the system saves the payment confirmation code returned by the gateway with the payment directive.
class PaymentDirective < ActiveRecord::Base
after_save :schedule_payment
def schedule_payment
update_attribute(:confirmation_code, GateWay.schedule(...))
end
end
The code above will result in an infinite loop(gulp) as the after_save callback is called upon updating the confirmation_code. We can address this issue
by adding a guard variable inside the method to store the state of an on going method invocation
def schedule_payment
return true if @schedule_payment_in_progresss
@schedule_payment_in_progresss = true
update_attribute(:confirmation_code, GateWay.schedule(...))
ensure
@schedule_payment_in_progresss = false
end
Now the code looses the readability. To address this issue, I implemented the recursion guard as an aspect.
def schedule_payment
update_attribute(:confirmation_code, GateWay.schedule(...))
end
recursion_guard :schedule_payment
I monkey patched the ActiveRecord class in a file called initializers/monkey_patches.rb.
class ActiveRecord::Base
def self.recursion_guard(method, on_guard_return_value=true)
old_method = instance_method(method)
define_method(method) do |*args|
begin
return on_guard_return_value if (instance_variable_get("@recursion_guard_for_#{method}") == true)
instance_variable_set("@recursion_guard_for_#{method}", true)
old_method.bind(self).call(*args)
ensure
instance_variable_set("@recursion_guard_for_#{method}", false)
end
end
end
end
Before you start the migration please be aware of these facts:
Heroku doesn’t migrate the data from the shared database to the dedicated database automatically.
Heroku doesn’t assign the dedicated database as the primary database automatically.
Heroku doesn’t remove the shared database even after you complete the migration. You have to remove it manually. Otherwise you will continue to incur charges(if any) for the shared database.
Instructions
Add the dedicated database to your application:
$ heroku addons:add heroku-postgresql:ronin
-----> Adding heroku-postgresql to sushi... done, v69 ($200/mo)
Attached as HEROKU_POSTGRESQL_RED
-----> The database should be available in 5-15 minutes
Use `heroku pg:wait` to track status
Track the progress of the database creation:
$ heroku pg:wait
Waiting for database HEROKU_POSTGRESQL_RED... done
Get the connection credentials of the newly created database
$ heroku pg:info
=== HEROKU_POSTGRESQL_BLACK
Plan Ronin
Status available
Data Size 5.1 MB
Tables 0
PG Version 9.0.5
Created 2011-10-10 17:59 UTC
Conn Info "host=ec2-107-22-255-345.compute-1.amazonaws.com
port=5432 dbname=dk2sf5va7dsalklkdsj3rd
user=uy5gymvzvyast6ee sslmode=require
password=pssajjhjhfa2yzx1q8g48dp1mo3a"
VS1: Verification step 1: Note down the count of users in the current database
$ heroku console
>> User.count
=> 1024
>> exit
Enable the mainenance mode. This will prevent any further changes to the shared database.
$ heroku maintenance:on
Create a backup of the shared database. Note down the backup id.
Let us say you have configured a custom domain; http://www.foobar.com; for the production environment of your application on Heroku.
You followed the instructions here to create a staging environment. Now, you want to expose the staging environment on http://staging.foobar.com.
I had a similar problem today, and I didn’t find any step by step instructions for addressing the problem.
Pre-requisites
Production and staging Heroku environments are called foobar-production and foobar-staging. Both environments have custom_domains add-on
The foobar-production environment has the Zerigo add-on. The A(foobar.com) and CNAME(www.foobar.com) records are configured using Zerigo add-on
Add the staging sub domain to point to the staging environment
Configure the Zerigo add-on to point to the staging environment.
Clone the CNAME record for www.foobar.com. The record points to proxy.heroku.com. Change the sub-domain name to staging.
Wait for 10 minutes for the changes to propagate. Access the staging environment using http://staging.foobar.com.
Let us say we have the following models in our project:
class User < ActiveRecord::Base
has_one :profile
attr_accessible :name
end
class Profile < ActiveRecord::Base
belongs_to :user
belongs_to :company
attr_accessible :location
end
class Company < ActiveRecord::Base
has_many :profiles
attr_accessible :name
end
In our view, we are trying to display user name, user location and user company name using
the code below:
<% @users.each do |user %>
<tr>
<td><%= @user.name %></td>
<td><%= @user.profile.location %></td>
<td><%= @user.profile.company.name %></td>
<tr>
<% end %>
We can DRY the code if we add a nested accessor to ActiveRecord class.
# user.read_nested("profile.location")
# user.read_nested("profile.company.name")
class ActiveRecord::Base
def read_nested(attrs)
attrs.split(".").reduce(self, &:send)
end
end
Now the view code can be rewritten as follows:
<% @users.each do |user| %>
<tr>
<% %w(name profile.location profile.company.name).each do |key| %>
<td><%= @user.read_nested(key)%></td>
<% end %>
<tr>
<% end %>
Recently, we needed a country select field for a form. We decided to use the official country select plugin from the rails team.
While testing the new UI, one of the team members noticed Taiwan was listed as:
Taiwan, Province of China
I was quite intrigued and decided to dig deeper to find out how rails community agreed for the transfer. The land grant can be found in the following line:
"Taiwan, Province of China", "Tajikistan", ....",
Why does Rails team call Taiwan a province of China?
As usual, there is always a simpler explanation for most of the conspiracy theories. It looks like the rails team took the official country names published by ISO.
The names in ISO 3166-1 - and thus on our Webpage - are taken from United Nations sources. These sources are authoritative inputs to the international country code standard. They are:
Since Taiwan is not a UN member it does not figure in the UN bulletin on country names. The printed edition of the publication Country and region codes for statistical use gives the name we use in ISO 3166-1. By adhering to UN sources the ISO 3166/MA stays politically neutral.
According to ISO it’s being politically neutral by following UN.
Why does UN call Taiwan a province of China?
This probably is a topic for a long form article for some journalist.
Code has consequences
This political dispute was fought via UN documents, media, text books and by influencing a foreign government to accept/reject Taiwan’s statehood. Until now, rest of the world didn’t have to take sides in this dispute. But now, rest of the world is unwittingly taking sides as more and more sites on the internet are using ISO-3166 as the source for the country names.
I favor the suggestion made by Dan Jacobson in this thread on Debian message board.
We (i.e. rest of the world) shouldn’t have to take sides, we shouldn’t have to choose between ‘Republic of China’ OR ‘Taiwan, Province of China’. We should simply call Taiwan as it’s commonly known, i.e. Taiwan.
I use the paperclip gem for attachment management. Recently, I installed ImageMagick to a location suggested by the installer on my laptop(running Windows 7-64bit).
C:\Program Files\ImageMagick-6.7.0-Q16
I set the command_path to a long file name in config\initializers\paperclip.rb.
When I tried to upload an image, the server threw an error.
[paperclip] An error was received while processing:
#<Paperclip::NotIdentifiedByImageMagickError: C:/.../Temp/xx.JPG
is not recognized by the 'identify' command.>
After some debugging I found a bug in the Paperclip gem in lib/paperclip/command_line.rbfile.
def full_path(binary)
[self.class.path, binary].compact.join("/")
end
The full_path function generates a long file name with a backslash.
"C:\Program Files\ImageMagick-6.7.0-Q16"/identify
This command fails on Windows as the cmd shell throws an error when the long file contains a back slash.
dir /x "C:\Program Files*"
dir /x "C:\Program Files\ImageMagick-6.7.0-Q16*"
Monkey patch the Paperclip gem in config\initializers\paperclip.rb.
class Paperclip::CommandLine
def full_path(binary)
[self.class.path, binary].compact.join((File::ALT_SEPARATOR||File::SEPARATOR))
end
end if defined?(Paperclip::CommandLine)
Now, the identify command is generated with the correct path seperator.
"C:\Program Files\ImageMagick-6.7.0-Q16"\identify
I prefer the second approach as command_path is easier to configure.
I recently got a new a new laptop. After installing Netbeans(6.9.1) on the machine, I tried to run the debugger as usual. Netbeans waited for around 10 seconds and refused to start the debugger. It took me a while to notice the brief error message in the status bar:
Could not connect to the web server... cannot show http://localhost:3000
After turning the IDE logging ON, I found the following exception in the IDE log file:
C:/r/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:29:in `gem_original_require': no such file to load -- require_relative (LoadError)
from C:/r/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:29:in `require'
from C:/r/lib/ruby/gems/1.8/gems/linecache-0.45/lib/linecache.rb:66
from C:/r/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:32:in `gem_original_require'
from C:/r/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:32:in `require'
from C:/r/lib/ruby/gems/1.8/gems/ruby-debug-base-0.10.4/lib/ruby-debug-base.rb:3
from C:/r/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:29:in `gem_original_require'
from C:/r/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:29:in `require'
from C:/r/lib/ruby/gems/1.8/gems/ruby-debug-ide-0.4.17.beta5/lib/ruby-debug-ide.rb:5
from C:/r/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:29:in `gem_original_require'
from C:/r/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:29:in `require'
from C:/r/lib/ruby/gems/1.8/gems/ruby-debug-ide-0.4.17.beta5/bin/rdebug-ide:7
from -e:1:in `load'
from -e:1
Today, I migrated to the latest version of the compass gem. Which required the latest version of the sass gem. The new sass gem broke my sass files as they were in sass 2 format.
I had the following gems installed on my machine:
compass (0.11.3)
sass (3.1.2)
haml (3.1.2)
After spending some time on Google I came across this article on sass2 to sass3 conversion. I ran the sass-convert tool.
Unknown format for sass-convert --from: sass2
Use --trace for backtrace.
I asked a question about this issue on the compass forum. It turns out the sass-convert tool honored the sass2 input format
in sass 3.0 gem. The latest version does not support sass2. I did the following to get the conversion working:
New York-based artist Matt Wisniewski creates mixed media images that are beautifully refreshing. His digital art collages create a stunning fashion...