Episode 34: Named Routes

Posted over 7 years back at Railscasts

When you add a custom route, make it a named route so you have url helper methods to easily link to that new route. See episode for details.

Railsconf 2007 FTW

Posted over 7 years back at zerosum dirt(nap) - Home

Had a great time at Railsconf 2007! Just got back. A little jetlagged, and in need of (another) nap. In summary: lots of good presentations, superb microbrews, a hilarious zefrank performance, and a number of lurking lolcats.

Highlights for me included DHH’s keynote, the Rails way ‘live’ performance by Jamis and Koz (although I have to politely disagree with them on the need for private ActiveRecord attributes), Ezra’s deployment and scaling session, and the homesteading talk by Matthew Bass. Thanks to everyone who helped make it happen.

Also got to meet some fellow IRC peeps in person. Now ur tru idinty is nown to me, bewar!

Episode 33: Making a Plugin

Posted over 7 years back at Railscasts

You can sometimes remove a lot of duplication by generating methods dynamic. In this episode I will show you how to create a plugin which does exactly that.

Only In Kenya

Posted over 7 years back at Sporkmonger

As a few of you are probably aware by now, I will be taking a break from Ruby, and computing in general for a couple of months. I am getting on a plane headed for Nairobi on May 20th. I won’t be back until August 26th. I’m not taking a computer with me, though I will have limited access through internet cafes, so email should work, but don’t expect quick replies.

For those who are curious, the intent of the trip is humanitarian in nature. There will be trips to Uganda and Tanzania, and some volcano climbing. I’ll be sure to take lots of photos, which will no doubt end up on Flickr.

Update:

In London. About to fall asleep.

Update:

In Kenya. Amazingly still awake.

Episode 32: Time in Text Field

Posted over 7 years back at Railscasts

Although Rails does allow you to edit time attributes with text fields, it's not very flexible. In this episode you will learn how to use a virtual attribute to format the time to your liking.

RailsConf '07 and SF geekSessions

Posted over 7 years back at PJ Hyett

The Err Free team will be accepting beers at RailsConf for anyone interested, come find us.

Chris will be talking about his acts_as_cached plugin on Saturday. He promised me it’s gonna be good and he’s not one to disappoint.

Also, if you’re going to be in the Bay area after RailsConf, there’s a three hour session on the 22nd concerning whether Rails can scale.

It’s $15, has smart people talking, and there’s an open bar afterwards…need I say more? Check it out.

RailsConf '07 and SF geekSessions

Posted over 7 years back at PJ Hyett

The Err Free team will be accepting beers at RailsConf for anyone interested, come find us.

Chris will be talking about his acts_as_cached plugin on Saturday. He promised me it’s gonna be good and he’s not one to disappoint.

Also, if you’re going to be in the Bay area after RailsConf, there’s a three hour session on the 22nd concerning whether Rails can scale.

It’s $15, has smart people talking, and there’s an open bar afterwards…need I say more? Check it out.

Oregon

Posted over 7 years back at zerosum dirt(nap) - Home

So here I am in sunny Oregon. Around 1PM I hop on a train headed to Portland for RailsConf 07. Came out a few days early to catch up with my good buddy Ty in Eugene and work on the startup idea we’ve been banging around. And do some hiking, drinking, and dissecting of Heroes too, of course.

I kind of love being out here and yet still having my internal clock set to east coast time. I wake up “early” for a change, and bang out a nasty chunk of work before anyone else here is even awake yet. Otoh, I feel like an old man when I begin to falter around 11PM. Heh.

Anyway, I’m looking forward to the conference. I’ll be attending the tutorials day tomorrow, specifically the scaling session with Joyent’s Jason Hoffman as well as David Black’s ‘Routing Roundup’. If you see me, say hi.

Backup of Bloglines keep new items

Posted over 7 years back at Spejman On Rails

If you are a Bloglines user, you probably save the interesting posts using "keep new" feature.

If you have use this reader for a time, the quantity of post saved could be large... Some day I thought that won't be funny to loose all this data, then I build a ruby script to backup bloglines "keep new" items into a xml file.

With this script I learned better Mechanize and Hpricot Ruby libraries.
Este script me ha servido para probar dos librerías muy útiles de Ruby: mechanize y hpricot.

You need these libraries in order to use the script:


gem install json
gem install activesupport
gem install hpricot
gem install mechanize


And here you have the script. I think is very understandable. I hope it helps you to backup your bloglines account (remember to change EMAIL and PASSWORD values with yours) or to understand better how mechanize and hpricot works.

require "rubygems"
require "hpricot"
require "json"
require "mechanize"
require "active_support"

# Reads a bloglines javascript tree structure that has all
# feeds data.
def read_tree( tree_base, label = "" )
tree_base.each do |tree|
if tree["kids"]
read_tree tree["kids"], label + "/" + tree["n"]
else
@feeds << [tree["n"], label, tree["kn"], "http://www.bloglines.com/myblogs_display?sub=#{tree["id"]}&site=#{tree["sid"]}"]
end
end
end

# Add more memory to hpricot otherwise couldn't load some webs.
Hpricot.buffer_size = 262144

agent = WWW::Mechanize.new
page = agent.get 'http://www.bloglines.com/login'

form = page.forms[1]
form.email = 'EMAIL'
form.password = 'PASSWORD'

page = agent.submit form

# Get the bloglines sindicated feeds
menu_page = agent.get "http://www.bloglines.com/myblogs_subs"
start_text = "var initTreeData = "
end_text = "\n;\n"
js_feeds_tree_str = menu_page.content[menu_page.content.index(start_text)+start_text.size..menu_page.content.index(end_text)]
feeds_tree = JSON.parse js_feeds_tree_str.gsub("\\","")
@feeds = []
read_tree(feeds_tree["kids"])

puts "<bloglines_saves>"
@feeds.each do |feed|

page = agent.get feed[3]
doc= Hpricot(page.content)

# get the content of all saved feed posts
content = ((doc/"body")/"td.article")
next if content.empty?
puts "<feed name=\"#{feed[0].strip}\" folder=\"#{feed[1].strip}\">"

# Iterate each saved feed post
((doc/"body")/"a.bl_itemtitle").each_with_index do |title, index|
puts "<feed_save title=\"#{title.inner_html.strip}\" href=\"#{title.attributes["href"]}\">"
puts content[index].inner_html.to_xs
puts "</feed_save>"
end
puts "</feed>"

end
puts "</bloglines_saves>"

Más información:

Hampton Catlin - Ruby on Rails Podcast

Posted over 7 years back at Ruby on Rails Podcast

The author of HAML rants on markup, Macs, diversity, and tech writing.
Also mentioned

Capistrano Off the Beaten Path

Posted over 7 years back at Revolution On Rails

Introduction

If you use Capistrano, most likely you use it to deploy rails applications by running it from the project directory. The plugem management tool piggy-backs on Capistrano to execute some recipes without using the current path because recipes operate on gems. Recipes do not, however, completely ignore the current directory, but instead use it for optional customization. Customization is not limited to a deployment recipe from the current directory but can be environment-specific across multiple sites if they each have a special extension gem installed.

Background

We use a bunch of ruby scripts at RHG for deployment and delivery of our numerous applications and shared component. When we started preparing some of that functionality for a public release, we needed to provide a way to customize the scripts. Warren Konkel suggested to migrate them to Capistrano since it was the most familiar tool for rails developers and it has a recipes hierarchy that can be used for customization. So, we wrote the plugem command tool that feeds its parameters to Capistrano via Capistrano::CLI.new(plugem_converted_arguments).execute!
after loading its own recipes.

The Code

    1 module Capistrano
2 class Configuration
3
4 alias :standard_cap_load :load
5
6 def load(*args, &block)
7
8 standard_cap_load(*args, &block)
9
10 if args == ["standard"]
11
12 load_plugem_deploy_recipes(File.dirname(__FILE__) + '/../..')
13
14 begin
15 require 'plugems_deploy_ext'
16 load_plugem_deploy_recipes(PLUGEMS_DEPLOY_EXT_DIR) # Overriding from extensions
17 rescue Exception
18 # No extension is loaded
19 end
20
21 end
22
23 end
24
25 def load_plugem_deploy_recipes(dir)
26 Dir[File.join(dir, 'recipes', '*')].each { |f| standard_cap_load(f) }
27 end
28
29 end
30 end

Ignoring lines 14-19 for now, all it does is inject the plugem deployment gem recipes to Capistrano. They are now available for execution by Capistrano. So when I call plugem update my_app it is being translated to cap plugem_update -s plugem_name=my_app(we use the plugem_ namespace for tasks and variables to avoid clashing with standard recipes). Since loading of plugem recipes is purposely not handled via the -f flag of capistrano, the standard deployment recipes like config/deploy.rb are still being loaded.

Customization

The package is extending Capistrano but we wanted it to be customized too. For example, you might want to define your own list of gem servers to download gems from. Capistrano allows to define recipes per project, user, or host. The plugems_deploy takes it a step further and provides a way to customize it per deployment environment, which might contain many hosts. It does this by expecting an optional plugems_deploy_ext gem to be installed on a system (lines 14-19). If it finds the extension gem, it loads recipes from there overriding the default ones.


Conclusion

Capistrano is not only a great deployment tool, it can be used as a base of highly-customizable general purpose tools.

Capistrano Off the Beaten Path

Posted over 7 years back at Revolution On Rails

Introduction

If you use Capistrano, most likely you use it to deploy rails applications by running it from the project directory. The plugem management tool piggy-backs on Capistrano to execute some recipes without using the current path because recipes operate on gems. Recipes do not, however, completely ignore the current directory, but instead use it for optional customization. Customization is not limited to a deployment recipe from the current directory but can be environment-specific across multiple sites if they each have a special extension gem installed.

Background

We use a bunch of ruby scripts at RHG for deployment and delivery of our numerous applications and shared component. When we started preparing some of that functionality for a public release, we needed to provide a way to customize the scripts. Warren Konkel suggested to migrate them to Capistrano since it was the most familiar tool for rails developers and it has a recipes hierarchy that can be used for customization. So, we wrote the plugem command tool that feeds its parameters to Capistrano via Capistrano::CLI.new(plugem_converted_arguments).execute!
after loading its own recipes.

The Code

    1 module Capistrano
2 class Configuration
3
4 alias :standard_cap_load :load
5
6 def load(*args, &block)
7
8 standard_cap_load(*args, &block)
9
10 if args == ["standard"]
11
12 load_plugem_deploy_recipes(File.dirname(__FILE__) + '/../..')
13
14 begin
15 require 'plugems_deploy_ext'
16 load_plugem_deploy_recipes(PLUGEMS_DEPLOY_EXT_DIR) # Overriding from extensions
17 rescue Exception
18 # No extension is loaded
19 end
20
21 end
22
23 end
24
25 def load_plugem_deploy_recipes(dir)
26 Dir[File.join(dir, 'recipes', '*')].each { |f| standard_cap_load(f) }
27 end
28
29 end
30 end

Ignoring lines 14-19 for now, all it does is inject the plugem deployment gem recipes to Capistrano. They are now available for execution by Capistrano. So when I call plugem update my_app it is being translated to cap plugem_update -s plugem_name=my_app(we use the plugem_ namespace for tasks and variables to avoid clashing with standard recipes). Since loading of plugem recipes is purposely not handled via the -f flag of capistrano, the standard deployment recipes like config/deploy.rb are still being loaded.

Customization

The package is extending Capistrano but we wanted it to be customized too. For example, you might want to define your own list of gem servers to download gems from. Capistrano allows to define recipes per project, user, or host. The plugems_deploy takes it a step further and provides a way to customize it per deployment environment, which might contain many hosts. It does this by expecting an optional plugems_deploy_ext gem to be installed on a system (lines 14-19). If it finds the extension gem, it loads recipes from there overriding the default ones.


Conclusion

Capistrano is not only a great deployment tool, it can be used as a base of highly-customizable general purpose tools.

Episode 31: Formatting Time

Posted over 7 years back at Railscasts

Learn how to use the trusty strftime method to format a time, and see how Rails allows you to save this format for later use.

Wayfaring Stranger

Posted over 7 years back at PJ Hyett

With all of this talk of the future, I’d be remiss not to mention the other website that I’m apart of that’s been chugging along for almost two years now:

Wayfaring! With the team working at CNET last year we haven’t been able to give it much love, but we did manage to upgrade the Google Maps API to version 2 and even built a version for Land Rover.

Some quick stats:

  • 29k users
  • 35k maps
  • 101k waypoints

It has a very loyal following and its design is still fresh, have a look.

Plugin I Cannot Live Without

Posted over 7 years back at Revolution On Rails

The Enhanced Rails Migrations plugin was written to end the constant battle we had with clashing names in db migrations within our large development team. We tried everything: special commit policies, rake tasks, even claiming the next migration number in subversion. Nothing worked and CI server was sending 'broken build due to conflicting migration number' messages almost daily. Since the plugin was introduced to all our rails applications around six months ago, I have not heard of a single case of conflicting migrations. Seemingly, the goal was well accomplished.

What I found over time, is that the plugin is not only useful for large projects. Any rails development effort with more than one programmer involved benefits from using it. If you ever had to renumber your new migration after doing svn up you know what I am talking about. It makes sense to install this plugin as the very first one in your project since an amount of migrations at the beginning tends to grow much faster then later in the game.

The plugin works for rails versions 1.1.6 up to the latest edge. When you start your next project with multiple developers, use it and you should be able to forget that you ever had problems with clashing migrations.