Archive for the ‘Ruby’ Category

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

Friday, 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.

Ubuntu 10.4 rubygems fails with zlib error

Thursday, 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

My Month-A-Page Calendar

Sunday, 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.