Rails on Ubuntu 9.10 with Ruby 1.9.1
Here's a short list of what I needed to get Rails 2.3.5 running on Ubuntu 9.10 with unixodbc support on Ruby 1.9.1
install ubuntu 9.10 sudo apt-get install ssh libssl-dev libreadline5-dev git-core mysql-server pdftk zlib1g zlib1g-dev libmysqlclient16-dev haproxy unixodbc unixodbc-dev freetds-common freetds-dev tdsodbc nginx freetds-bin postfix install ruby1.9.1 from source ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.1-p376.tar.gz update rubygems sudo gem update --system http://wiki.rubyonrails.org/database-support/ms-sql ruby-odbc from source http://www.ch-werner.de/rubyodbc/ruby-odbc-0.9997.tar.gz sudo gem install rails mysql prawn vpim activerecord-sqlserver-adapter dbd-odbc dbi daemons configure unixodbc and freetds, and haproxy and nginx install mongrel gem 1.1.6 sudo gem install mongrel --source http://gems.rubyinstaller.org need to add self signed cert https://help.ubuntu.com/8.04/serverguide/C/certificates-and-security.html add deploy user and certificates for git repo etc.
MountainWest RubyConf
Was MountainWest RubyConf awesome? You be the judge:
Special Thanks to Mike Moore and Pat Eyler for putting on a great conference. The speakers were great and the atmosphere was top notch.
cap deploy:web:enable
I have finally decided to start putting up a warning page when doing maintenance on one of my sites. I decided that I wanted to use capistrano to get the job done. I checked the cap -T task list and noticed that there was already one there. It was pretty bleak looking so I decided to just roll my own page and put up a task to change the filename when needed and it would be picked up by nginx and displayed. I made up a page and put in on my production server under the system folder in the shared path and named it m.html. I then wrote up a couple of cap tasks to manage the renaming of the file and put them into my deploy.rb file:
desc "Turn on Maintenance Mode"
task :maint_on, :hosts => @web do
run "mv #{shared_path}/system/m.html #{shared_path}/system/maintenance.html"
end
desc "Turn off Maintenance Mode"
task :maint_off, :hosts => @web do
run "mv #{shared_path}/system/maintenance.html #{shared_path}/system/m.html"
end
disclaimer: there is probably already a way to do this using the original deploy:web:enable, but I didn't want to figure it out.
Ruby Business Days in the Future
Going the other way now
1 2 # takes the number of days in the past you are looking for 3 # like 10 business days ago 4 start_date ||= Date.today 5 start_day_of_week = start_date.cwday #Date.today.cwday 6 ans = 0 7 # find the number of weeks 8 weeks = num / 5.0 9 #puts "yields #{weeks} weeks" 10 11 temp_num = num > 5 ? 5 : num 12 #puts "first temp num #{temp_num}" 13 14 begin 15 16 ans += days_to_adjust_f(start_day_of_week,temp_num) 17 #puts "ans in loop #{ans}" 18 19 weeks -= 1.0 20 #puts "weeks in loop #{weeks}" 21 22 temp_num = (weeks >= 1) ? 5 : num % 5 23 #puts "temp_num after loop #{temp_num}" 24 end while weeks > 0 25 26 #puts "#{start_date} - #{num} - #{ans}" 27 days_ago = start_date + num + ans 28 29 end 30 31 32 33 34 ansr = 0 35 case start_day_of_week 36 when 1 37 if 5 == num then ansr += 2 end 38 when 2 39 if (4..5).include?(num) then ansr += 2 end 40 when 3 41 if (3..5).include?(num) then ansr += 2 end 42 when 4 43 if (2..5).include?(num) then ansr += 2 end 44 when 5 45 if (1..5).include?(num) then ansr += 2 end 46 when 6 47 if (1..5).include?(num) then ansr += 1 end 48 when 7 49 #do nothing 50 end 51 return ansr 52 end
Ruby Business Days ago
My attempt at writing a solution to finding the number of business days ago from a specific date. I am using this in a Rails App.
1 2 # takes the number of days in the past you are looking for 3 # like 10 business days ago 4 start_date ||= Date.today 5 start_day_of_week = start_date.cwday #Date.today.cwday 6 ans = 0 7 # find the number of weeks 8 weeks = num / 5.0 9 #puts "yields #{weeks} weeks" 10 11 temp_num = num > 5 ? 5 : num 12 #puts "first temp num #{temp_num}" 13 14 begin 15 16 ans += days_to_adjust(start_day_of_week,temp_num) 17 #puts "ans in loop #{ans}" 18 19 weeks -= 1.0 20 #puts "weeks in loop #{weeks}" 21 22 temp_num = (weeks >= 1) ? 5 : num % 5 23 #puts "temp_num after loop #{temp_num}" 24 end while weeks > 0 25 26 #puts "#{start_date} - #{num} - #{ans}" 27 days_ago = start_date - num - ans 28 29 end 30 31 32 33 34 ansr = 0 35 case start_day_of_week 36 when 1 37 if (1..5).include?(num) then ansr += 2 end 38 when 2 39 if (2..5).include?(num) then ansr += 2 end 40 when 3 41 if (3..5).include?(num) then ansr += 2 end 42 when 4 43 if (4..5).include?(num) then ansr += 2 end 44 when 5 45 if 5 == num then ansr += 2 end 46 when 6 47 # no adj 48 when 7 49 if (1..5).include?(num) then ansr += 1 end 50 end 51 return ansr 52 end
jRuby Rails mssql server
Database.yml for connecting to a MS Sql Server using jdbc
development: adapter: jdbc driver: com.microsoft.jdbc.sqlserver.SQLServerDriver url: jdbc:microsoft:sqlserver://someserver.domain.local:1433;databaseName=some_db;AutoCommit=false; username: someuser password: somepassword
Ruby Procs
I was writing a script to port some data to a new database last night when I noticed that I had used the same bit of logic several times. I thought I'd better DRY up my code. I could have written a method, but I thought I'd try a proc instead. Below is the result:
Before: if ssr[27] == 1 cc3 = 1 elsif ssr[28] == 1 cc3 = 2 end if ssr[33] == 1 cc8 = 1 elsif ssr[34] == 1 cc8 = 2 end if ssr[39] == 1 cc13 = 1 elsif ssr[40] == 1 cc13 = 2 end if ssr[82] == 1 da5 = 1 elsif ssr[83] == 1 da5 = 2 end
After:
find_true = Proc.new { |field1, field2|
if field1 == 1
1
elsif field2 == 1
2
end
}
cc3 = find_true.call(ssr[27],ssr[28])
cc8 = find_true.call(ssr[33],ssr[34])
cc13 = find_true.call(ssr[39],ssr[40])
da5 = find_true.call(ssr[82],ssr[83])
Rails select options
I am developing an application where I have a dropdown list of hours worked on a project. The spec is that it should be in quarter hour increments using a decimal notation. So, 0, 0.25, 0.50, 0.75, etc. The select helper in rails takes an array of arrays that would look like this: [[0,0],[.25,.25], etc...]. I needed to generate that array and this is what I came up with:
def labor_hours
ar = []
(0..39).each do |n|
a = n.to_f
b = a + 0.25
c = a + 0.50
d = a + 0.75
ar.push([sprintf('%0.2f', a), a],[sprintf('%0.2f', b), b],[sprintf('%0.2f', c), c],[sprintf('%0.2f', d), d])
end
ar.push(["40.00",40])
end
I start by creating the array that I'm going to return. I then use a range and a block to loop over 0 to 39. I have to made sure that I convert the integers to floats and add my partial hours. I then create my arrays for this integer and add them to the final array. At the last second, I add the last array for a nice even 40 hours. Works pretty well. I used sprintf to format the floats so that everything has 2 decimal places instead of some with one and some with two.
So, my view code looks like this:
<%= form.select 'labor', labor_hours, :include_blank => true %>
enum#inject
One of the very handy features of Ruby is the use of blocks. Blocks allow us to interate over a collection of some kind (think arrays) and perform some action on each item in the collection. This gives rise to methods like enum#inject. This handy little method of the enumerable module allows us to do summation operations on the contents of a collection. It looks like this:
(1..5).inject {|sum, n| sum + n}
=> 15
If you are new to Ruby, the (1..5) is a range, basically equal to [1,2,3,4,5] an array of 1 through 5. The inject method uses an accumulator object, sum in this case. It loops over the array passing in each object and adding the object to sum and finally returning sum which is 15 in this case.
One very handy use for this method is summing totals for tables in RoR. If you have a collection of objects that have a price variable for instance, you could do something like this to get a total instead of trying to keep a running total as you output the rows containing the objects' data.
@items.inject(0.0) {|memo, u| u.price + memo}
Here each item object in the @items array has a price. We give it a starting value of 0.0 to create a float object for our accumulator and let inject add all of the prices together to get our total. It is a slick way to accumulate totals on a array. Hopefully you can find a use for it too.
Twitter