Setting the explicit gem path in a rails application

July 5th, 2010

This is one of the more frustrating problems I’ve been having lately.  I install (or move) an application on my shared host and it can’t find any gems. I can start a script/console and see them, but I can’t get the app to see them.

The problem is that script/console takes into account the ~/.bash_profile, which includes settings for GEM_PATH and GEM_HOME.  Passenger doesn’t use those settings, so it only uses the system gems.  Naturally, when you’re on a shared host or exprimenting with different projects, you don’t want to install _everything_ to the system, so here’s the workaround:

In you environment/production.rb file, you can add explicit GEM_* settings that point to your gem home.  In my case, I added:

ENV['GEM_PATH'] = '/home/yourusername/.gems:/usr/lib/ruby/gems/1.8'

The nice part is that you can set the GEM_HOME or any other environment variables that you need later.

Odd problem with gem push “Home does not appear to be a valid URL”

July 2nd, 2010

While trying to push a gem this morning, I kept getting a weird problem called

“Home does not appear to be a valid URL”

I searched all over, and once again, I’m the only person that has ever had this problem.  But, I did find the error in the gemcutter source.  Effectively, I needed to make sure that the .gemspec had a valid URL for the homepage value.

If you have that problem, this may be your solution.

Pointing spree at Network Merchants Inc.

June 8th, 2010

After some consideration, this is the fastest way I’ve found to get Spree Commerce working with Network Merchants (nmi.com)

1.  Create an authorize.net payment method.

Admin->Configuration->Payment Methods->New Payment Method

name it something like “Credit Card” and select provider of “Gateway::AuthorizeNet”.  Not “Gateway::AuthorizeNetCim”

Save.  now there are new options for configuration.  The server should be “live” without quotes, test mode should be unchecked, and login is “demo” with a password of “password”.  Again, don’t use the quotes for either value.

If you try and process an order now, you’ll probably get the error

Unable to Authorize Credit Card: Gateway Error … The merchant login ID or password is invalid or the account is inactive.

That’s because it’s still pointing to the authorize.net server.  You need it to point to NMI.

2.  Modify the gateway to point to NMI

In

config/initializers/spree.rb

add the following lines at the end of the file

ActiveMerchant::Billing::AuthorizeNetGateway.test_url=”https://secure.networkmerchants.com/gateway/transact.dll

ActiveMerchant::Billing::AuthorizeNetGateway.live_url=”https://secure.networkmerchants.com/gateway/transact.dll

Restart and give it a try.  This should allow your spree commerce solution to use the NMI Emulator for authorization AND capture of credit card orders.

CC# 4111111111111111

Date: Any time in the future

CCV: 123

If that works, go back and change the login and password to be what NMI issued you for the gateway.  Then you’re live and ready to start taking credit cards.

Cloning VirtualBox Hard Drives

May 28th, 2010

If you need to copy/paste a virtualbox box, you can’t just make a new file. You have to use a command something like this from the .virtualbox/harddrives directory:
C:\Users\Muzik\.VirtualBox\HardDisks>”\Program Files\Sun\VirtualBox\VBoxManage.exe” clonehd Ubuntu10_4.vdi Ubuntu10_4_JavaDev.vdi

Starting New Java Projects

May 28th, 2010

I’ve been working with Ruby and Rails for some time now.  One of the things I like about Rails is that you can start a new project with one command.  The result is a working web server, MVC structure, tests, ORM, db configuration, and build process.

Now I needed to do that in Java.  I’ve worked on Java projects for the last 10 years, and I’ve written my share of Ant scripts.  I didn’t want to start from scratch, so I looked around for some examples of a simple ant script with a separate code, build, and test directory that would create a jar.  Maybe even deploy that jar to a directory.

This is a common problem.  Every well-formed Java project has to be able to do this.  You have to be able to compile and deploy software for it to work.  I thought this would be easy.  But I was wrong.  In Java, there are so many options for each of these pieces that it takes hours to decide on what software to use, what version to use, and integrate that software into a working build, test, and deploy process.

Hours.

After a couple of hours, I realized I wasn’t going to find it.  First, I had to decide on and download an ORM, testing framework, database connectors, and web server.  Then I had to put them all together in a working format.

Now, I know this has to be done for every project, but the thing is, it only has to be done ONCE. Once it’s set up, you can forget about most of what you’ve done and just get right back to work.

So I started looking for another solution.  I remembered something about appfuse, so I looked it up.  It had one update last year, and that was the first in 18 months, so that’s not very encouraging.  The blog post about it mentioned five other options that solved the same problem, so I decided to check them out.

Spring Roo sound interesting.  Get coding in minutes.  But the example is way over the top:  Use one line of code to get a .class file with all this advanced instrumentation.

But even so, if you’re going to use spring it sounds like Roo is the way to get up and running fast.  And I like that there is training and a certificationUPDATE:  you can only get certified if you take the training, so I’m not as impressed.

JBoss Seam is another contender.  It has more limitations, but if you’re already committed to JBoss, why not get the biggest bang for you buck?  They also have training (including virtual training with half-day classes) and cert. for an administrator, but not a developer.

So for now I’m going to try Spring Roo.  I have a couple of learning curves to climb, but I like the idea of deploying to tomcat instead of JBoss just because it’s a leaner tool.  I’ll post back with updates.

Ubuntu 10.4 rubygems fails with zlib error

May 13th, 2010

After fiddling with installing ruby and rubygems from source on my shiney new Ubuntu 10.4 install, I kept running into a problem with the gem command.

custom_require.rb:31in ‘gem_original_require’:no such file to load — zlib (LoadError)

To fix this, I did these things as root:

apt-get install zlib-bin zlib1g-dev

cd /usr/local/src/ruby-*/ext/zlib

ruby extconf.rb –with-zlib-include=/usr/include –with-zlib-lib=/usr/lib make

make

install

How YOU can work with vim

October 22nd, 2008

I recently saw a great podcast on reddit titled  “How I work:  Rails with Vim” (http://blip.tv/file/1372096).  It showed how the author had made shortcuts to use vim more effectively.  Specifically, how to do a find from the current directory, get a list of files, and jump to any of those files.  TextMate fans will recognize this as a project file list with the ability to jump to that file.  Also the demo had a vim plugin that would do some replacements.

While it’s neat to see what he had done, the screen cast didn’t say _how_ he had done it.  It was almost like he had this cool funcitonality, which I was excitited to start using, but there were no instructions on how _I_ could use it.

So, I spent a little time figuring it out.  Here’s what I came up with:

VIM-

This is an alias to get a list of files in the current directory and below, and load that into vim.  Here’s my version

alias vim-=”find . -name .svn -prune -o -type f -print |vim -R -”
This finds all files (not directories “-type f”) under the current directory and prunes the .svn directories.  It then reads this list into vim from standard out.  It reads the file list as read-only “-R” so that you don’t have to worry about saving it or doing q! to get out of the editor

NOTE:  The find command may take some time with large code bases.

Next, change your vimrc file so that control T opens a new window with the file under the cursor
map <Ctrl-T> :new <cfile><Enter>
Apparently, <cfile> is the file name under the cursor.  You can use vnew instead of new to get a vertical window to the right.
Also, you can put this line in the vimrc to make the window open below the current window instead of above.
set splitbelow

Grill

The author also had a script that does a grep that is recursive, case insensitive, and lists the matching file names and puts that into a vim editor.  Here is my version.

I don’t know enough about aliases in bash to take arguments, so I just wrote a script.  My ~/bin directory is in my path, so I created a script called grill with this line
grep -ril $1 . |grep -v “.svn”  |vim -R -

Now “grill user” will open a vim window with a list of files that have the word user in them, and control-T will jump into that file.

Replacements

The last feature of this demo was the ability to input a shortcut and get several more keystrokes.  For this I use AutoHotKey in windows.  It is a great little utility that allows you to type “/ult/” and a tab, and it erases /utl/ and inserts /user/local/tools/tomcat*/apache*/, or whatever else you want.  It’s great for naviaging long paths or abbreviating frequent logins.  Now J@H maps to joe@hotmail.com<tab> password <enter> and it pops up on the screen as if you had done it yourself.  It’s very impressive in demos, and it works in any window, not just vim.

My Month-A-Page Calendar

October 5th, 2008

Recently I needed to present data that relates to a month’s worth of appointments in Ruby.  In one scenario, the user might have 6 or 7 appointments on the same day for a dozen days in the month.  In another scenario they may only have 2 in a month.  Either way, I wanted to show the entire month and the title of each appointment on a calendar that took up the whole screen.

I looked for plugins, but nothing seemed to fit the bill.  Most of the plugins are for choosing a specific date (and time).  I downloaded and installed the calendar_helper plugin, but it didn’t seem to fit the bill, either.  Not until I dig in and played with it did I see that this was just what I was looking for.

Here’s how I got it to work:

First, install calendar helper

script/plugin install http://topfunky.net/svn/plugins/calendar_helper/

Then create the appointment model

script/generate model appointment name:string starts_at:datetime duration:integer
 exists  app/models/
 exists  test/unit/
 ... and so on

Update the database

rake db:migrate

Next, create a new controller, an index page, and a detail page

script/generate controller appointments index detail
 exists  app/controllers/
 exists  app/helpers/
 create  app/views/appointments
 exists  test/functional/
 create  app/controllers/appointments_controller.rb
 create  test/functional/appointments_controller_test.rb
 create  app/helpers/appointments_helper.rb
 create  app/views/appointments/index.html.erb
 create  app/views/appointments/detail.html.erb

And add it to the routes and bounce the app

map.resources :appointments

In the controller, we’ll want to set the default year and month to the current one.  We’ll also want to get the list of appointments for the needed month.  For simplicity’s sake, I’m just going to hard code some appointments here.  They will all be for the current day.

class AppointmentsController < ApplicationController
def index
@cal_time = Time.now
@appointments = []
@appointments << Appointment.new(:name=>"Lunch with the Boss", :starts_at=>Time.now.change(:hour=>12, :minute=>0) )
@appointments << Appointment.new(:name=>"Interview - Big Corporation", :starts_at=>Time.now.change(:hour=>8, :minute=>0) )
@appointments << Appointment.new(:name=>"Interview - Hot Startup", :starts_at=>Time.now.change(:hour=>3, :minute=>30) )
end
...

In the view we will need to do two things:

  1. We don’t want to loop through all the appointments for every day, so in order to handle the data intelligently, we’ll make an array with an entry for each day of the month.  All the appointments that fall on a particular day will be added to an array for that day.  This should make sense shortly.  If not, you can skip this part for now.
  2. We want to create a calendar with calendar_helper, and on each day we want a link to each appointment on that day.

To achieve number one here is the code

#Collect all the days into an array of arrays, so we can pull them out by day
appt_by_day = [];             # Holds arrays of appointments by day of month
@appointments.each{ |apt|
day = apt.starts_at.mday
if appt_by_day[day].nil?    # If this day does not have an array
appt_by_day[day] = []     # Then make one
end
appt_by_day[day].push(apt)  # Add this appointment to this day
}

To achieve number two, we use the calendar helper with the block that does processing for each day

calendar(:year => @cal_time.year, :month => @cal_time.month,  # 1
:previous_month_text=>"<a href='/make_this_smarter'><<</a>", #2
:next_month_text=>"<a href='/make_this_smarter'>>></a>"
) do |d|
display_string = ""                                #3
if !appt_by_day[d.mday].nil?                       #4
apt_for_day = appt_by_day[d.mday]
end
apt_for_day.each{ |a|                              #5
display_string += "<a href='/appointments/detail/#{a.id}'>#{a.name}</a><br>"
}
end
["<div class='dateBox'>#{d.mday}</div><br><div class='appt'>#{display_string}</div>" ] #6
end

This code does several things

  1. On this first line it sets the year and month for the calendar.  These should be integers.
  2. At number 2 and the next line it sets the URL for the next and previous month links.  These are left as an exercise to the user.
  3. This block runs for each day of the month, with the day as “d”.  The display_string is the string we want to display for this day.  It should contain a link to the detailed view for all the appointments for this day.
  4. The appt_by_day array for each day will either be nil (no appointments) or an array of appointments, since you can have several in the same day.
  5. The array of today’s appointments is in apt_for_day.  For each of these we want to add a link to the display_string for display.  Once we have the whole string we’ll send it to the helper.
  6. This line tells the helper what we want to display in the box.  I have put the day and the display_string in different divs, just to make formatting easier.

This works, but it’s pretty ugly.  The boxes for each day are too small, and there aren’t enough colors.

To make it nicer we need to install the css.

script/generate calendar_styles

This gives us some pretty css that the calendar can use.  Edit the views/layout/appointments.html.erb to look more like this

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

<html xmlns=”http://www.w3.org/1999/xhtml” xml:lang=”en” lang=”en”><head>
<meta http-equiv=”content-type” content=”text/html;charset=UTF-8″ />
<title>Events: <%= controller.action_name %></title>
<%= stylesheet_link_tag ’scaffold’ %>
<%= stylesheet_link_tag ‘calendar/blue/style’ %>
</head>
<body>

<p style=”color: green”><%= flash[:notice] %></p>

<%= yield  %>

</body>
</html>

I added some css details for the divs we created and got this (picture was taken the next day):

Next up will be making it as wide as the screen, adjusting the colors, and making the users happy.

Taking full advantage of the flexibility of calendar_helper allowed me to deliver a full-screen view of a month with all the calendar information within easy reach of the user.

Blogging is like working on the bathroom.

June 15th, 2008

Recently I noticed that the floor in my bathroom was uneven.  Near the toilet the linoleum had an odd line it where the floor underneath was curled up a little.  We had only lived in this house six months and I knew that this was a new problem, but we had family in for a week and I had just broken my leg, so I let it go for a while.

About a month later I was a little more mobile, and I started to investigate.  Let me preface this by saying I’m kind of a handy guy, but I had never worked on bathrooms or flooring.  I started by looking at the sink and toilet in that bathroom.  The sink looked fine, but the toilet’s bolts that held it to the floor were loose.  That’s not good.  I emptied the toilet and took it off (first time for me) and saw that the floor around it had started to weaken.  So, I started pulling up linoleum (first time again).  The floor underneath this was “underlayment” which is particle board for the floor to sit on, and it looked like the toilet had been leaking into the underlayment, which became swollen, and that’s the problem we were seeing.  Around this time my wife starts talking about replacing the linoleum with hard wood floors.

At this point, I’m a little out of my depth.  I call my dad, who is very handy, and talk to some people at Lowe’s.  Everybody says floors are easy, and I figure I’ll need a plumber and carpenter to put things back together, but I certainly don’t need them to take things apart.  I mean, I can see that the underlayment needs to be replaced, and surely I can pull that out.  So I do (another first).  But that means removing the vanity, washer, dryer, pictures, and baseboards (another first).  Then I cut into the underlayment and start prying it up.

Under the underlayment, theres a “subfloor”.  This is what sits on the joists that holds us up.  The subfloor is in really good shape, except for a couple of square feet around the toilet that needs to be replaced because it was wet and now it is weakened.  Again, I ask around, look on the internet, buy a new saw (yipee!) and figure out how to replace it.  Then we decide on new flooring, figure out how to install it, and get it in.  Then we still have to get the vanity (with new counter top and faucets, thanks honey) back in, washer, dryer, baseboards (which now need varnish) and, finally, the toilet.

All that was because, while trying to wash my hands, I thougth “Huh.  That line on the floor shouldn’t be there.”

That’s how blogging is for me.  I start with one topic, which leads to another, which leads to another.  I started a post on training this morning, which lead to some thoughts on how prepared you REALLY need to be, which lead to a rant on continuous integration (which, like linoleum, I never spell right) which led to a catchy title for the post, which made me realize I now had at least 3 topics in the same post and I forgot where I was going in the first place.

Sometimes trying to do the simplest thing turns out to be a lot of work.