Below you will find pages that utilize the taxonomy term “Rails”
look ma no hands tweeting with your voice
This is just another one of those boring weekends where I felt the need to hack on something.
If you follow Google Chrome's blog you're probably aware of this little nifty feature they started to implement in their latest builds: HTML5 voice recognition.
And that's when it struck me: "Hey, what if I use that and tweet with my voice instead of typing?"
The result of this hacking session is LoudParrot, a sample Rails app that shows how to do just that. You will need a fairly recent build of Google Chrome -beta - which you can download here.
You can get the source on GitHub.
ide review rubymine
Since I started working with Ruby about 4 years ago, I've used quite a few text editors and ide's: RadRails, gedit + plugins, TextMate and Vim.
TextMate is the one I've used the most and it's been ok for a long time. Until you realize you need half a dozen bundles to make it really useful for ruby development. Obviously the same goes for Vim and gedit.
Oh, and forget about refactoring. In these tools refactoring equals regex global replace. So if you need it, well, forget it.
That's when I decided to give RubyMine a fair go. I've been using it heavily for a while now and I must say I love it!
What pissed me off about RadRails when I first tried it was the speed. It was too slow, something people take for granted when running java based IDE's.
However this is not true for RubyMine. You DO take a hit on startup, nothing major, but once it's done, it's a breeze.
I've compiled a list of my favorite productivity shortcuts and features. Hope it'll be useful to someone else.
Productivity Shortcuts
Navigation
Ctrl + Tab - File Switcher
Cmd + Shift + T - Switching between implementation and test works perfectly. Even in a pure ruby project
Cmd + Shift + F12 - Expand/restore editor
Alt + Shift + N - Go to model/view/controller
Alt + F1 - Show current file in other views such as the project tree (scroll to file)
Cmd + Shift + N - Open file
Cmd + Alt + Shift + N - Open symbol - across files
Alt + F7 - Find usages - when on a method, variable, etc…
Running/Debugging
Ctrl + Shift + F10 - Run current [test] file. When inside a test method, run that single method.
Ctrl + Shift + F9 - Same as above, but in debug mode.
Shift + F10/Shift + F9 - Run/Debug last action executed
Alt + R - Run rake task
Refactoring
Cmd + Alt + N - Inline variable/ method
Cmd + Alt + M - Extract method
Shift + F6 - Rename
F5 - Copy current file as...
Editing
Cmd + Y - Delete line
Cmd + D - Duplicate Line/Selection
Alt + Mouse - Column selection
Cmd + Shift + (Up Arrow|Down Arrow) - Moves de line or selected block of code up or down
Features
Code completion - It's fairly accurate and pretty fast. They've done some good yak shaving around this area.
Debugger - The debugging interface is an absolute beauty. Saved me a lot of time where I'd have used puts statements or googled to re-learn how to use ruby-debug instead. Definitely worth checking out.
The bad stuff
It is not free - unless you are a committer to an open-source project. But it's not expensive either.
It is a bit slower - but not that much. The performance hit is insignificant compared to the added value.
Regex file open, TextMate style - What can I say? I do miss this.
Wrap highlighted text - In TextMate, if you highlight a word and press ", [, {, ( or # it surrounds the word with the respective combination of quotes, brackets, etc... Another missed feature
Wrapping up
It's probably soon to say it but so far RubyMine has been my missing Ruby IDE. And I'm very happy with it. :)
clouds against the floods presentation available
Last Tuesday I gave a short presentation on the whole Clouds Against the Floods thing at the Ruby on Rails Oceania User Group here in Sydney.
Those guys are awesome and they recorded the talk - thanks guys!
If you'd like to download the slides, they're available on Slideshare.
Enjoy! ;)
update to appconstants it can now be used as a gem
This is just a quick post to let you know that AppConstants can now be used as gem!
Just add it to your Gemfile and 'bundle install' it:
#in your Gemfile
gem "app_constants"
#in the console
$ bundle install
$ rails generate app_constants
#then follow the instructions on-screen instructions
It can also be used without Rails. Check out full instructions on the GitHub repository.
Feedback welcome :)
clouds against the floods
I think by now everyone's heard of the hard time the guys up in Queensland, Australia are having because of the recent floods. People have lost their lives and many others have lost their homes and businesses, product of years of hard work.
As a result of this massive disaster the Queensland Government decided to run a telethon to encourage donations to help the flood victims. The Telethon aired last Sunday, 09/01/11, on Channel 9 and lasted for 2 hours.
The problem was the existing donations system that the Government had been using so far: it was just not thought out to handle the load we were expecting to have on Sunday.
That's when my employer, ThoughtWorks, kindly offered a hand to Smart Services Queensland in the attempt to make sure they could receive all donations that were likely to come through the web.
After that, on the Thursday afternoon before the event, Phillip Calçado, Ben Barnard and I set off on a mission against the clock: we had a little over 48 hours to develop, test and deploy an application that was expected to handle thousands of users. Not only that but an application that, should it fail, would prevent millions of dollars from reaching the people in need in Queensland. This was a great responsibility but we knew we could do it.
Given the time constraints it was a bit obvious that we would use Ruby on Rails for this app. Both because of the productivity it's known for and because we had the knowledge right there. With that out of the way, we had to decide how and where we would deploy this thing. We thought a little about it and came down to to 2 options: Amazon EC2 or Heroku (which is powered by Amazon EC2 under the hood). I pushed hard for Heroku and that's what we ended up going with.
Now it was time to get down and dirty and start coding the app. In principle it should be fairly simple. It needed a form where a potential donor would fill out his/her information, giving the option to receive the tax receipt by email or regular mail - more on that later. Upon clicking submit users would be taken to the secure payment gateway website where they could input their credit card number and finish the payment, after which they would be taken back to our app with a success - or an error - message and a transaction number.
Now this work flow has a couple of implications: First, all emails would have to be sent in the background so as to not interfere with the website performance. We were expecting to be sending thousands of them - workers anyone?
Second, the payment gateway integration would have to be developed and tested from scratch. Up until now the Queensland Government integrated with it in a different manner that could not be reused in this case.
And most important of all, although simple in concept, we had no idea of the load we should be preparing for. There was just no data from previous telethons. Thus we decided to prepare for the maximum we possibly could.
As we developed the application we deployed continuously to Heroku in order to test the payment gateway integration, benchmark the app using Apache AB, setup cache headers - Heroku uses Varnish - and find bottlenecks.
Email was one of these bottlenecks and that's why we decided to handle that in the background using Delayed::Jobs.
Since the first deployment, we also tweaked a couple of things at Heroku, such as migrating from their free PostgreSQL offering to a dedicated instance that we believed would both take the load and have plenty of room for all the data - as I write this post, we are already well over the 5MB limit they offer for free.
Long story short, by Saturday evening the website was up and running on 5 app instances, a 6th instance running background jobs - sending emails - and a dedicated PostgreSQL database server.
As Heroku is outside the Government network, their SMTP server was a no go on the short term so we also integrated the app with SendGrid, an email delivery service that fitted perfectly our needs - although the site got so much traction that we went over our monthly quota with them. But the nice guys from SendGrid increased our limit after I opened a ticket explaining the situation!
As for performance we used NewRelic to monitor the application, which Heroku also makes a breeze to integrate with.
We all went home to rest and get ready for Sunday, the day of the Telethon, when we would be monitoring the app throughout the day. We were all excited and when the show went live, we started seeing all those beautiful access charts moving like crazy, spiking over 720 requests per minute and being solid like a rock with flat and fast response times throughout the night.
In about two hours we had over AUD$2,000,000.00 (two million) donated through our website.
Since then the number of transactions dropped but has stayed constant and as of today we've received AUD$25,438,518.32 (over 25 millions of dollars) that will be donated to the flood victims in Queensland.
Oh, and the site is still up and going strong so move your fingers and go help: telethon.smartservice.qld.gov.au - there will be heaps of people grateful for your donation.
small update to appconstants
It's been now over a week since we moved to Sydney and everything is just great. We're still house hunting but I got a feeling we'll have a home soon. :)
In the meantime, this morning I got a feature request on github to allow AppConstants to interpret YAML files with embedded code like this:
I haven't needed it myself but thought it would be a nice addition so my latest commit does exactly that. Let me know if you find any issues.
upgrading appconstants to rails 3
Back in January I announced a small but useful plugin called AppConstants, that basically provides a central place where you can store environment specific constants. And since I started using Rails 3 in the past week, I thought I'd make it Rails 3 compatible.
The code is really simple and - as I expected - the upgrade process was quite straight forward.
I'm not gonna write a guide here on how to upgrade your plugins to Rails 3 - there is plenty about that around the web - but instead, just show the steps I went through to upgrade mine. Similar plugins might have a similar upgrade path.
- Generators
My plugin makes use of a simple generator that copies its default constants file and initializer to Rails.root/config and Rails.root/config/initializers, respectively. In Rails 2.x it was located under Rails.root/vendor/plugins/app_constants/generators/app_constants and it was defined like so:
In Rails 3, the generators had to be moved to Rails.root/vendor/plugins/app_constants/lib/generators. Notice the root directory app_constants under generators has been removed as well. And the code was changed to this:
We had three simple changes here:
- The generator now extends from Rails::Generators::Base: This class uses the Thor infrastructure to handle generators. - more info here.
- I had to implement the source_root class method, which basically tells your generator where to find your template files.
- The manifest method is now called copy_config_files - or anything you want.
The way this works is that, once you invoke the generator, Thor will sequentially call all instance methods in your generator class - or the only instance method in the example above. If your generator does a lot, it will allow for a better organization of your tasks.
And that's it! I did change a couple of other things but that had to be changed anyway and are not related to the migration.
For Rails 2.3.x users, you'll find a 2.3.x branch on github that should work for you.
Cheers
my take on rails environment specific constants
It’s funny how every Rails application I - and possibly you - work on ends up needing some sort of per-environment global constants.
Examples may include the application url - It might be used in account activation emails and thus should be different between the development and production environments.
Or perhaps your application depends on external services that, depending on the environment, are available in different URIs.
There are a couple solutions out there but my needs were simple and straightforward, thus I developed a small rails plugin that is the simplest thing that could possibly work: AppConstants.
It's been useful for my current project and I hope it can be useful to someone else too ;)
monit thinking sphinx and rvm
In one of my Rails projects I'm using Sphinx to provide full-text search capabilities. To integrate both worlds I chose Thinking Sphinx, which is just great and so far has met all of my expectations.
Also, as I previously mentioned, I'm using RVM to manage my ruby installations on both my development and production machines and this setup is what motivated this post.
I use Monit to monitor the services running on my production server - nginx, mysql, php - and as of the first deploy of this application, it only made sense to also monitor Sphinx.
In order to create an initialization script, I would need at least a way to start and stop sphinx from the command line, which, using Thinking Sphinx, can be done using these rake tasks:
$ rake thinking_sphinx:stop
$ rake thinking_sphinx:start
It's worth mentioning now that I don't run sphinx as root. I run it with the same user my rails application uses. For the purpose of this post, let's call it deploy.
When I tried using my script I got errors such as these:
Missing the Rails 2.3.5 gem. Please `gem install -v=2.3.5 rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.
After some digging around I found that the GEM_HOME environment variable for my deploy user wasn't being set correctly - something to do with rvm, but not quite sure - and to fix this, well, I just had to set it, leaving the final working version of my script somewhat like this - simplified :
#! /bin/sh
### BEGIN INIT INFO
### END INIT INFO
set_path="cd /your/rails/app/root; export GEM_HOME=/path/to/your/gems; RAILS_ENV=production;"
case "$1" in
start)
echo -n "Starting sphinx: "
su - deploy -c "$set_path rake ts:start" >> /var/log/sphinx.log 2>&1
echo "done."
;;
stop)
echo -n "Stopping sphinx: "
su - deploy -c "$set_path rake ts:stop" >> /var/log/sphinx.log 2>&1
echo "done."
;;
*)
N=/etc/init.d/sphinx
echo "Usage: $N {start|stop}" >&2
exit 1
;;
esac
exit 0
There are 2 things happening here. First, regardless of the user I’m running this init script as, I drop privileges in order to execute the rake task with my deploy user. Second, I set the GEM_HOME environment variable to stop getting the ‘gem not found’ errors.
After that, monit was able not only to monitor my sphinx instance, but also (re)start/stop it with the correct user.
I’m no Linux wizard so if you wanna suggest improvements to this script, feel free to do so!
rails summit 2009 im speaking
I'll be speaking at this year's Rails Summit Latin America in Sao Paulo, Brazil. It will be a good opportunity to meet some amazing people and visit friends back home! :)
Overall I'll be spending 12 days in Brazil, with 2 of them dedicated to the conference. The other 10 I'll be in Rio de Janeiro visiting my family and friends. I strongly advise you to spend some time in Rio too, if at all possible. It's an amazing city and you can contact me if you have any questions.
Back to the conference, my session is called JRuby in the enterprise world: Using Rails with legacy code, and will be given in the form of a tutorial. I will walk you through some problems we had while making this kind of integration at my company, focusing mostly on dependency management.
At the end I hope you'll have a good understanding of what JRuby is capable of in a legacy environment.
If you're planning to attend and would like to hear anything specific about JRuby, please let me know, I can try and squeeze in.
C u there!
rails rumble 09
Update: The service is now down while we move it from the VPS provided by Rails Rumble to our own. I'll let you know once it's up.
Last weekend Philip, Pedro and myself got together for this year's Rails Rumble.
We haven't had really decided what to do until a few days before the competition, but I had this really simple idea and decided to go with it. Seems people liked it, given a few positive comments we received.
So, after 48 hours - which were not used to work full-time in the application - The Bird Watcher was born.
The Bird Watcher is a simple way to show the world what's going on on Twitter for any topic you define. Go ahead and take a look at the website to see a live example.
We're planning to keep the service up after the competition is over and we have some nice features lined up to go live on the next release.
In short, it was an interesting weekend and showed me that this team works really well together.
Cheers
jruby on rails and legacy java apps managing dependencies
The motivation for this post came from a couple of messages I've seen on the jruby's google group and because I think it's pretty cool to share how we tackled this problem.
- A little bit of context
We, as a vast amount of people out there, have legacy Java code. A lot. In our case this legacy is pretty much crucial to our business. We can't just trash it and start from scratch. Bad idea.
On the other hand we do have new features to be built on top of it. But we wanted an easier way to develop this new stuff and decided for a JRuby on Rails solution, using it as a front-end to our existing services.
- What we decided to do
Our final rails project would make use of a specially created jar file containing our Java application. This Jar would also contain a public interface of the services we'd have to interact with from rails.
As any Java application, ours depend on a number of external jar files that correspond to the various framewoks we usually have in place. e.g.: Hibernate, Spring, apache-commons ...
Which means we need to make our app's jar and all it's dependencies available in the JRuby classpath in order to use it.
Given we're using warbler to package our application as a war file, we just need to place all jars needed into our rails app's lib folder. Warbler then takes care of copying any jar files located in there into the war.
- The problem
So we needed a smart way to include all these dependencies into the project, and copy/paste isn't an option.
In the Java world we use Maven to manage our projects dependencies - and you should too. Because of that our approach involved turning our rails application into a Maven aware project.
Basically we needed a pom file that would declaratively list our java project as a dependency. From there on, Maven knows what the dependencies are and downloads them to your local repository.
Which leaves us with one more task. We need to put all these dependencies into our lib folder after maven has downloaded them.
Below you'll find the pom.xml file that we use to achieve this with inline comments explaining each bit:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.company</groupId>
<!-- notice how we specify the packaging to be a war,
that way, maven knows where to copy the jar files -->
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<artifactId>railsApp</artifactId>
<name>railsApp</name>
<dependencies>
<dependency>
<groupId>com.company</groupId>
<artifactId>java-legacy-app</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>railsApp</finalName>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<!-- This tasks only creates a basic structure expected by maven,
so it can do its work -->
<id>create-mock-web-descriptor</id>
<phase>compile</phase>
<configuration>
<executable>/bin/sh</executable>
<workingDirectory>.</workingDirectory>
<arguments>
<argument>-c</argument>
<argument>
mkdir -p src/main/webapp/WEB-INF
touch src/main/webapp/WEB-INF/web.xml
</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
<execution>
<!-- Now in the package phase we copy the jar files
that maven put into the fake web app to our rails' lib folder -->
<id>copy-needed-jars-into-lib</id>
<phase>package</phase>
<configuration>
<executable>/bin/sh</executable>
<workingDirectory>.</workingDirectory>
<arguments>
<argument>-c</argument>
<argument>
rm -f lib/*.jar
cp target/railsApp/WEB-INF/lib/*.jar lib
rm -rf target/railsApp*
rm -rf src
</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
<execution>
<!-- Here we optionally create the final war file containing our rails app using warbler,
doing a small cleanup of the files and folders maven created -->
<id>create-final-war</id>
<phase>package</phase>
<configuration>
<executable>/bin/sh</executable>
<workingDirectory>.</workingDirectory>
<arguments>
<argument>-c</argument>
<argument>
rm -rf *.war tmp/war
jruby -S warble && \
mv *.war target/railsApp.war
</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Now from the command line we can just run mvn package and we’re good to go.
Maven will start to package the application as a war file. Since it’s not a Java application we create the empty web.xml file in the compile phase, to fool maven.
After it has copied all the dependencies into WEB-INF/lib the next packaging goals will make sure we copy them to our rails’ lib folder, also creating the final war file, ready for deployment.
Note that once done, you can use a simple code snippet similar to this one as an initializer and load all dependencies:
Dir.entries("#{RAILS_ROOT}/lib").sort.each do |entry|
if entry =~ /.jar$/
require entry
end
end
Then we can just use script/console, script/server and so on, as we normally would.
Sorry for the long post, I tried to pack in as much as I could and I certainly hope it’s useful to someone. Any doubts, comments and etc… just drop me a line. :)
rails readable test names run individual tests from the console
As you probably know, since rails 2.1 you can write test methods in the following format:
test "hotel should return its permalink" do
#your test code here
end
Which is great, as the test name becomes much more clear. But you can't simply run this test easily from the command line. You'd have to run something like:
$ ruby your_test_file.rb -n test_hotel_should_return_its_permalink
It annoys me. And it's not practical either to make the test fail just so you can get the test's real name.
I wanted to be able to just copy and paste the readable name in the console and have Test::Unit do the conversion and run it for me, like this:
$ ruby your_test_file.rb -n "hotel should return its permalink"
So I created readable_test_names_runner. It's a tiny rails plugin that adds this feature for you.
Enjoy.
rcov jruby and rcov_plugin
The rcov_plugin project is a rails plugin for rcov that adds some useful rake tasks to your application. And since I'm currently working in a JRuby project it made sense to use this plugin.
The thing is, among other stuff, an rcov report from a JRuby project includes some files that shouldn't be there at all, plus you also need to change the way you call rcov as such. Thus, I thought I'd contribute these changes to the plugin and my pull request was approved this morning - just install the latest version and you should be good to go.
It was useful for us here, hope it might be useful for you too.
Enjoy :)
jruby on rails and google app engine
As many of you know the new language supported at GAE now is Java, as officially announced on their blog. As a Ruby/Rails developer you might not be interested on it but here is a reason you should be: JRuby.
It was only a matter of time until we saw some people deploying JRuby on Rails apps on GAE, like Ola Bini's mini blog app. Guess that was the first one really, as he was beta testing the service in secret. Google App Engine imposes a few catches to any java application deployed there and any JRuby app wouldn't be different. For instance, your Java API access is limited to these classes - called JRE Class whitelist.
As you can see on his blog, you don't need active record and in fact shouldn't even be loading that on your app.
I felt compelled to try it and the timing was perfect. I am currently developing a JRuby on Rails app at the company I work for and it was a perfect fit, since we are not using ActiveRecord. The reason is that we get the data we need from other sources, such as web services and even text files.
Ola Bini's tips were crucial here. He provides a small script you can use to prepare the jars you're sending to your app. Another important piece was the Google App Engine SDK for Java. It ships with a server that emulates GAE's behaviour locally so you're less likely to have problems once you deploy it.
I did have a problem though with the number of files uploaded to my appspot. It's currently limited to 1000 - a thousand - and a Rails app can easily exceed this limit. So before deploying, remove anything that is not crucial: activerecord - you should've done it already - , all tests directories - including the ones inside gems your app needs in order to work, fixtures and etc.
After that it was rewarding seeing a custom JRuby On Rails application working perfectly on GAE. And as much as I'd like to, I can't really share the URL since it's a private app but I encourage people to try it. I believe GAE will ultimately help the community improve JRuby even more.
And as a last tip, this time thanks to Fabio Akita, is this snippet. You should redirect your log so you can debug your app form GAE's dashboard.
Have fun!
rails performance scripts profiler benchmarker
There are several ways you can measure your rails application's performance. The techniques range from filling your code with "puts" statements - :p - to fancy ones like NewRelic - which is quite nice, I must say.
But what many people don't know is that rails ships with a handful of scripts to help you out. One of which is called profiler, located under your application's scripts/performance directory.
By default it uses the standard ruby profiler but if you want more speed - and additional reporting options - , consider installing the ruby-prof gem.
So if you execute it without params, you'll get a clue of how it works:
$ script/performance/profiler
Usage: ./script/performance/profiler 'Person.expensive_method(10)' [times] [flat|graph|graph_html]
Pretty self explanatory, right?
As a sample code, I have in my rails app a dumb model with a really dumb method I wanna profile:
class Article
def self.find_all_with_delay
sleep 10
self.find(:all)
end
end
Clearly this method doesn't perform well and is a bottle neck in our super application! But let's see what rails' profiler tells us:
$ script/performance/profiler 'Article.find_all_with_delay' 1 graph > text_graph.perf
Loading Rails...
Using the ruby-prof extension.
Thread ID: 109440
Total Time: 10.147995
%total %self total self wait child calls Name
--------------------------------------------------------------------------------
100.00% 0.00% 10.15 0.00 0.00 10.15 1 Global#[No method] (/Users/leo/projects/test/vendor/rails/railties/lib/commands/performance/profiler.rb:24} /Users/leo/projects/test/vendor/rails/railties/lib/commands/performance/profiler.rb:24
10.15 0.00 0.00 10.15 1/1 Object#profile_me
--------------------------------------------------------------------------------
10.15 0.00 0.00 10.15 1/1 Global#[No method]
100.00% 0.00% 10.15 0.00 0.00 10.15 1 Object#profile_me ((eval):1} (eval):1
0.00 0.00 0.00 0.00 1/1 Class#const_missing
10.15 0.00 0.00 10.15 1/1
dont use rexml i mean it
REXML is the standard XML processing library for Ruby. It's on Ruby's core and is terribly slow.
Yeah, I know it's pretty simple to use, got a nice interface and, again, it's just there. And it is a good library, for most things. But if you, as me, came to a point that processing XML is taking 50% of the time to render a rails action, it's time to change.
My tip? Use libxml instead. The numbers on their home page speak for themselves. Try it yourself, you won't be disappointed. And I'm really happy with the performance increase on our app.
railsconf europe 2008 impressions and highlights
I'm back in Madrid again after the RailsConf and I think it's time to say something about it. :)
First off, the infrastructure provided by the conference was really great. The rooms, WiFi connection, food... Really well organized.
Now to the sessions, highlights:
Tutorials (Tuesday)
- Meta-programming Ruby for fun and profit (Neal Ford, Patrick Farley)
The old and good techniques that made Ruby so powerful. Here Neal and Patrick walked us through the main tricks to meta programming like open classes - and conditionally open them - , dynamically define methods, sending messages to objects and how Ruby can help test your Java code in a much easier way.
I've put the link to the slides but honestly I don't think they're too much useful without the talking.
Sessions (Wednessday)
- EC2, MapReduce and Distributed processing (Jonathan Dahl)
Jonathan explained the theory behind MapReduce using very simple ruby examples, providing the basics on how to distribute and paralelize tasks accross multiple machines.
He also introduced Hadoop, a platform built in Java that "lets one easily write and run applications that process vast amounts of data". What I liked the most was the simplicity he explained this subject. As of today, his presentation is not available online. Stay tuned as I'm gonna update this post with the links, as soon as they're available.
Sessions (Thursday)
- Debugging & Testing the Web Tier (Neal Ford)
If you've been concerned about testing your app's web tier lately, this presentation would probably not show you anything new. Neal talks about the need to debug and test javascript behaviour accross multiple browsers, using tools like Firebug, JSUnit and Selenium. If you have no idea about what these tools are, please stop now and go evaluate them!
We are pretty concerned about testing on my actual job, but selenium tests can be a pain sometimes - a.k.a extremely slow. And what ends up happening is that they are forgotten. Developers only run the test suite if it's not painful and it's lightning fast. Here's is where the highlight for this session comes: CrossCheck.
The idea is to be able to test your javascript code accross multiple browsers without the need to launch them. In fact, you don't even need a browser installed. The negative point is that it's kinda fallen behind because now you can only test older versions of browsers. But since the project is getting a lot of traction, I'm pretty sure this will be solved soon.
Conclusion
My overall impression of the other sessions I attended is that some speakers just didn't have time to properly prepare themselves, what made me think this years's RailsConf wasn't all that I expected.
But I also met interesting people and after all one of the key points in a conference is networking. :)
Definitely worth it though. And that's why I took the time to provide this highlights.
c u soon
railsconf europe 2008 heading to berlin
The title says it already.
On monday I'll be going to Berlin to attend this year´s RailsConf.
This will be my first one and of course my expectations are pretty high!
As usual, after the conference I'll try and give a summary of what happened there, providing as much content as I can.
Anyone else's going??? :)
C u there!
mac os x getting mysql and rails to work
So I couldn't resist and bought myself a MacBook Pro! It's my first week with my new toy and I'm really enjoying it.
But I need to do something useful with it so I started to prepare it to be my new development platform, starting with Ruby/Rails + MySQL: Here is where the fun begins!
After I installed both Rails and MySQL, I fired up a terminal an typed:
sudo gem install mysql
...and here is what u get
ERROR: Failed to build gem native extension.
If you google this error you will find a couple solutions and this is the one that worked for me:
ARCHFLAGS="-Os -arch x86_64 -fno-common"
sudo gem install mysql -- --with-mysql-dir=/usr/local/mysql
--with-mysql-config=/usr/local/mysql/bin/mysql_config
Now, confident enough, I created a sample rails app and tried to create the development database:
leo$ rake db:create (in /Users/leo/projects/test)
dyld: lazy symbol binding failed: Symbol not found: _mysql_init
Doesn't look happy yet huh? This took me a while to figure out but it turned out to be fairly simple.
I have no idea why but after I installed the gem I had the file mysql.bundle in two different places:
/Library/Ruby/Gems/1.8/gems/mysql-2.7/lib/mysql.bundle
/Library/Ruby/Gems/1.8/gems/mysql-2.7/mysql.bundle
The solution was to remove the first copy of the file. Now everything is working fine at this end!
I really hope this is useful to someone!
rails vulnerability on rexml
REXML, the XML library uses by many ruby apps, including rails, has a vulnerability that requires an immediate patch on whatever rails version you're using.
Details and instructions on the official rails weblog, here.
But basically, this is what you need to do:
gem install rexml-expansion-fix
Then, require rexml-expansion-fix in your rails's app environment.rb file.
the biggest rails event in latin america
Behold latin american railers!
This year we will have the Rails Summit Latin America on October, 15th and 16th, in São Paulo, Brazil.
It's by far the biggest Rails event we've ever had, including many of the speakers that were present at RailsConf.
Fábio Akita is also one of the speakers and provides more details on his blog.
If you're a assumed rails geek don't miss the opportunity to hear from the big names and to know a beautiful country like Brazil.
Oh, btw, if you're brazilian, like me, you have no excuse to miss this party!
Enjoy!!!
passenger mod_rails and problems with custom apache installation
This week we started to test mod_rails in a couple of projects where I work on. One in production.
Of course it's too early for any conclusions, but I just wanted to share a couple of problems you might find when the installer tries to compile the Apache module.
In our case, and I believe it is the case of many servers out there, we have a custom Apache installation, what makes the installer not find it and/or not find the Apache Portable Runtime (APR) sometimes.
The first one is easy and is documented here. You just seed to export the following environment variable, pointing to your apache installation:
export APXS2=/opt/apache2/bin/apxs
The second one is a bit tricky but it happened only when I tried to install passenger in another server that had CentOS. In this case, you will also need the following environment variable, pointing to your Apache APR config:
export APR_CONFIG=/usr/local/apache2/bin/apr-1-config
It took me a fair amount of time googling around to find this answer, so I hope it'll be useful for someone. :)
euruko 2008 materials available
As some of you know I went to the European Ruby Conf in Prague, this year.
The event was awesome and it's good to know they finally made available the majority of the slides, here.
They also published Matz's keynote, and more videos from the conference are being edited right now, so stay tuned to their home page!
Enjoy!
a couple of things from here
It's been some time since my last post but here I am! Where? In Spain, of course! Having a great time, I must say.
I arrived last week in Madrid and the past 2 weeks before that I spent basically packing my stuff. There is still some paperwork going on but everything is flowing well.
Besides this little feedback, I was reading this week's issue of the excellent series This Week In Ruby, from my friend Antonio Cangiano. I found something quite interesting, a plugin called HoboFields.
One of the things that bothers me in rails is the fact that by looking at your model classes, you can't tell the fields you have there. Sure, you can look at the migration script. Yeah, you can also load the development environment and inspect the object. It's a pain in the @zz! But this is the way ActiveRecord works...
Other ORM solutions like DataMapper, allows you to define the fields directly in the class. It's a much cleaner and clear way to maintain your models. And you get to know what properties you have just by looking at your classes.
That's exactly what HoboFields adds to ActiveRecord.
You define your properties and its types straight into your model class, and the plugin creates the migration scripts for you. Coming from a java world my self, I find it rather interesting, useful and it also reminds me of the way Hibernate works. You define your mappings with anotations in your class and hibernate just generate the schemas from there.
It's worth a try.
passengermod_rails released
Passenger(mod_rails) has been released.
The idea is to ease the pain on rails applications deployment. I tested myself and in less than five minutes I had my application working behind Apache!
I'm not going to say much here besides the fact that it seems like a really good option for rails deployment and people have been talking about it already, including DHH.
But I do recommend a read on the architecture overview document. Be sure to read it all, specially the part on handling concurrent requests.
To install, "it doesn't get easier than" that.
Good job guys.
jruby db2 xquery bug
Update: Follow up link to this issue on JRuby's Jira, here
As I told in my last post, it was time to give JRuby a serious try. So I took one of our rails projects at work and decided to migrate it to JRuby and see what happens.
We heavily use the XML capabilities of DB2 and this was a huge problem. Every query would work just fine through the activerecord-jdbc-adapter - part of the JRuby Extras . But every Xquery would gracefully fail!
After some debugging I got stuck and decided to get JRuby and activerecord-jdbc-adapter's source to see what was happening.
As I could see, it has a bug -in my opinion - at the java part of the code. The jdbc-adapter is a bridge to allow Active Record to talk with databases through native JDBC drivers, so it's normal that we do have a java part here. At this point, what the code does is to inspect the sql statement sent from ruby and decide if it's a select, update or insert.
I fixed the problem and submitted a patch to rubyforge. I'm not sure if it's the best solution or not, but now I got the xQueries working just fine.
I'd love to hear from people with similar environments whether this patch works for you or not. I'm sure I didn't try every possibility.
If you wanna try it, just drop me a message (e-mail in the About page) and I can send the pre-compiled jar file - for activerecord-jdbc-0.8
You can also just check out the code and compile yourself. ;)
qcon 2008 slides available
Most of last QCon's presentations are available for download here.
Highlights to Ola Bini's on JRuby(pdf) and Randy Shoup's on eBay's architectural principles(pdf).
And while we're talking about JRuby, it's impressive how it's becoming a recurrent and big subject. Fast. It had its own small space at big event like QCon and in the last Euruko in Prague, we had a presentation by the JRuby Core Developers Charles Nutter and Thomas Enebo.
Big companies are sponsoring JRuby's development indirectly or directly, like Sun. And other big companies are endorsing its production ready state, like Oracle, which has a publicly available website developed with JRuby On Rails.
It's past the time to give it a serious try...
euruko 2008 european rubyconf prague
On friday I'll be heading Prague for the European RubyConf.
Anyone is going? :)
Almost 300 attendees already registered for the event. And a few very interesting people will be speaking there like Matz and DHH (this one, through skype).
Besides that, the organization staff is scheduling 2 parties, friday and saturday, for the attendees.
Networking comes to mind, doesn't it? I think it will be a great opportunity to meet interesting and bright people.
So, see u in Prague!
openid
I think I've been really lucky lately. In my new job I'm getting to work with many interesting things and OpenID is just one of them.
We are investing high in Ruby on Rails and we have now a few internal applications in development stages. Our manager wanted the ability to let people log in to our rails applications(for now) using their OpenID accounts.
It was a funny task, as I knew very little about OpenID. The idea actually is really good. Instead of creating a new user account on each new service/site you'd like to subscribe to, you create a single user account in a OpenID provider - like MyOpenID - and use this identity to authenticate yourself in the services/sites that support this protocol.
What do we earn from that? Well, in my opinion, we can get a couple of benefits:
- You don't need to memorize 723 logins and 723 passwords (if you really care about creating different passwords for all of your user accounts)
- You don't authenticate yourself to the service you're attempting to use. This service actually asks to your provider if your identity is valid, and you authenticate yourself there. Nowhere else.
I strongly recommend you visit the OpenID to understand more about it.
But, back to the problem, we needed to put it working in a rails app. And that's when I found the ruby-openid library, provided by OpenID Enabled.
It is a complete library, really well documented that provides an abstraction layer both for consumer and server applications.
My first step was to develop the consumer. That's what you need if you are going to provide your users with OpenID authentication in your web site. The ruby-openid library comes with several samples that really helped me out here. They were developed using Ruby On Rails and are a really good start point.
After this step, I was asked to evaluate the possibility of being a OpenID provider. At first I thought it would be a really complicated task, but again this ruby library had a great example of a simple provider. The drawback is that the samples were developed in an older version of Rails ( < 2.x ) . So I had to freeze the Rails version to 1.2.5 so I could run the provider sample code.
I am now working on porting this code to Rails 2.x, into one of our applications and it's been flowing well so far. Just wanted to share this library for those of you trying something similar. It is really worth a look.
rails 20 xml data type and db2
[2008/04/30] Update: The ibm_db gem has been updated to support the new Rails 2.0 style migration. Now you can just use t.xml and it will work. Look here for more info. Thanks to Mario Briggs for pointing me to the update.
---
In my new job we work with XML data natively stored on DB2. I have done some test with Rails and DB2 a few weeks ago and it's pretty interesting, specially the easiness that Rails deals with XML.
We decided to test some new features of DB2 9.5 and I decided to test them with Rails 2.0.
So I created a new Rails app, configured the database.yml to use the idm_db gem and fired:$ rake db:create
The output is nice but, the database isn't there! I suppose it's something with the gem that needs to be updated. But really don't know about it. It just doesn't work. But this will not hold us down. I will just create the database by hand and keep going with my tests.
After that, I created a new model XmlDocument, which has a column named data, of type XML. According to the new migrations syntax, my model's migration would look something similar with this:class CreateXmlDocuments < ActiveRecord::Migration
def self.up
create_table :xml_documents do |t|
t.xml :data
t.timestamps
end
end
def self.down
drop_table :xml_documents
end
end
Right? Ok, I fired up a terminal and lauched:$ rake db:migrate
The output? Here it is:== 3 CreateXmlDocuments: migrating ============================================
-- create_table(:xml_documents)
rake aborted!
undefined method `xml' for #
Yes, a big nice exception! The new migration syntax doesn't allow you to do t.xml! But please don't ask me why! :p
The solution? Well, although it's weird - imo - , it's also easy. You can mix the new and the old syntax in the same file. So our model's migration will now look like this:class CreateXmlDocuments < ActiveRecord::Migration
def self.up
create_table :xml_documents do |t|
t.column :data, :xml
t.timestamps
end
end
def self.down
drop_table :xml_documents
end
end
And that's it! We're ready to go! I didn't find anything else different so far, besides what I described here. Hope this helps!
rails 20 scaffold
Following the Rails 2.0 hype, I've been playing around with it and decided to share a first impression: Scaffolding is gone!
But wait, before you knock your head against the wall, let me tell you something: I lied :)
Scaffolding is not really gone. It's just changed a bit.
How can I tell? Well, as a good developer I thought: "I'll just create a scaffold with the new version and see what's different"
I fired up a terminal, created a news rails application and generated a new model:$ script/generate model Contact name:string email:string
- yes you can do this in rails 2.0, and these fields get into your model's migration!
Now the I have a new model, it's time for a controller to manage it:$ script/generate controller Contacts
So your controller would look something like this huh?class ContactsController < ApplicationController
scaffold :contact
end
Well, too bad! The method scaffold is gone from ActionController::Base! And I'm not lying this time!
Now that the dynamic scaffold is gone, we're left with the static one.
Ok, let's try it then:$ script/generate scaffold contact
And it won't work again! ;) At the end of the output, you will get something like this:Another migration is already named create_contacts: db/migrate/001_create_contacts.rb
It really means that if your model is meant to be used by a scaffold, you better generate it in the same line. It will fail, afaik, if the model previously existed. Destroy yout model and controller, and execute the following:$ script/generate scaffold Contact name:string email:string
Done! Just run your migrations, startup your server and your new scaffold in rails 2.0 will be working gracefully!
It took me a while to discover this changes because I didn't find it well documented. But maybe I was not looking in the right places. :)
rubyworks production stack for rails
Well, we all know how hard, or at least cumbersome, it can be to set up a production environment to deploy your applications. Besides all the hardware stuff like storages, links, routers you are still left with a huge amount of software configuration to handle. This often includes configuring things like clusters, load balancing and services monitoring - Including notification of interested parts in case of any failure. Pieces of software you have to tie up and make them work together.
But hey, ruby lovers, you may have a better way to get this going! Released by ThoughtWorks, RubyWorks is, as quoted from their website, a production application stack for Ruby On Rails applications. I decided to give it a try and I really enjoyed it.
First of all I didn't want to mess with my actual configuration so I installed a new vm with Virtual Box. It has Ubuntu 7.10 on it, with 256MB of memory.
After installing RubyWorks - instructions on their website -, you get a new skeleton rails app up and running, being served by 4 mongrels that defaults to production environment! Impressed? There is more. A HAProxy is also set up in front of your mongrel servers acting as a load balancer.
Well, you probably want to monitor all that stuff huh? A monit web interface is waiting for your call on port 2812! It monitors all your mongrel servers - four by default - and your HAProxy, allowing you to measure CPU and Memory usage, among other things.
The coolest thing here is that all these softwares you would have to setup by hand are already working together, ready for production! Well, is it?
Going a little deeper, I deployed a database backed application to test this stack's performance.
I used Siege to stress the app and I am very happy with the results! I compared it with a single mongrel running on production env and no proxy at all.
It is worth mentioning that having 4 mongrels running took my vm to 77% of memory usage, while a single mongrel took it to 38%.