jose.costa

RailsConf 2010: Interview with George Guimarães 0

Posted by jose.costa
on Wednesday, July 28

Among the great people we met at the RailsConf was George Guimarães (@georgeguimaraes), by no surprise he was a very cool and funny dude, and he was open to talk and hang around with us.

George is co-founder of Plataforma Tec, that many of us got to know well through their amazing set of gems/plugins and the stunning work José Vailm has been doing as a Rails Core team member. Kind of what I hope it’s happening with the great work Santiago Pastorino is doing with his contributions and how it’s reinforcing WyeWorks reputation.

But still there are a lot of guys behind the scenes that support this great Open Source effort that’s being carried in these companies, probably not so much by direct intervention but with more hard and ‘real’ work as we like to say to joke around and bother the OSS guys. The kind of work that pay the bills :P

Not that George doesn’t do OSS, actually he’s currently involved in the development of Restfulie that got many people pretty excited at the RailsConf this year, and much more stuff.

Hope you enjoy this not so serious take.

Thanks George!

|

If you have found this material to be useful, you might
consider recommending me on Working With Rails.

jose.costa

RailsConf 2010: Interview with Fabio Akita 3

Posted by jose.costa
on Thursday, July 01

In the last day of the RailsConf 2010 Santiago and I got the pleasure to hang out a few hours with Fabio Akita, a very successful guy in the Ruby and Rails community, but yet so humble and open as many of the great people we met in these past days.

Fabio is well known as a great evangelist of this movement, as a great speaker, for his bundle of plugins for the vim editor but also for carrying interviews with important people of the community on every conference he attends. The thing is that personally I never got to see him as the subject of the interview, and he is a wise guy that has a lot to say. So even though he was very tired, he accepted to do this improvised short interview with me, almost the first time I was holding a camera.

This is the first of a small series of interviews that will be posted soon.

I hope you all enjoy it and share his thoughts on what are the good things that makes this community so special, so that we never loose that spirit.

Thanks Fabio!

|

If you have found this material to be useful, you might
consider recommending me on Working With Rails.

santiago.pastorino

Rails Bugmash an exciting first experience 3

Posted by santiago.pastorino
on Tuesday, January 19

As many of you must know, last weekend a Railsbridge Bugmash was celebrated, and I had the honor to be part of it for the first time. For those who are not aware about what this is, it’s a virtual event that takes place on irc.freenode.net at #railsbridge channel. The general idea of these events is to work on the Rails Core, taking a look at the Rails Issue Tracker. However, given that Rails 3 is about to see the light, this opportunity was intended to deeply test it looking for:

  • Fix a known issue
  • Report a bug
  • Make sure your favorite gem or plugin still works. If not, fork it and make it so.
  • Write a blog post about a certain component
  • Write some documentation
  • Get an app up and running and document what you had to do to upgrade.
  • Create a screencast

Each accepted contribution or patch done by a participant, gives him chances to win one of several prizes, the more contributions the more chances you have to win. For further details check out the Railsbridge Bugmash Guide and the RailsBridge Wiki.

Many bugs were fixed during the event, some plugins and gems were tested, really interesting discussions took place (specially regarding generators) and some other articles were made. To mention some:

And then Jose Valim, motivated by the posts done regarding rails 3 generators, published one himself called Discovering Rails 3 Generators

This was my first participation and it was a bloody great experience. During the event I was specially devoted to search bugs on Rails 3 and try to patch them. I managed myself to find 4 code bugs and 1 documentation bug, proposing a solution for all of them. One of them was not approved though, for there was a bigger problem that required José Valim’s intervention, the 3 other patches were approved.

I would also want to highlight the gigantic work done by the organizers, the core team members, and also to all the participants. I strongly valued the support José Valim, Pratik Naik and Michael Koziarski gave me. They were a hell of a help when trying to find solutions for the bugs. Would also want to thank Ryan Bigg for his cooperation, and specially to Sam Elliott, an incredible 18 year old guy with a great future ahead. Besides working together with Ryan and Sam, we kept a really nice chat during almost the entire bugmash. The awesome will to help at #railsbridge really overwhelmed me, where everybody was willing to help each other, something that makes it so much easier for the ones starting to contribute to Rails.

I would also want to congrat and thank all the participants for trying to make Rails better. So don’t hesitate to join the next time, it’s not as hard as I expected it to be and you would definitely not regret it. Now I’m really motivated to help others so I’m going to join to Rails Mentors on RailsBridge to give back the good things I received during this experience.

|

If you have found this material to be useful, you might
consider recommending me on Working With Rails.

santiago.pastorino

My Emacs for Rails 12

Posted by santiago.pastorino
on Friday, September 11

I’d like to share with the community my emacs init file and a set of plugins to give a nicer experience on Ruby on Rails development, which you can checkout from http://github.com/spastorino/my_emacs_for_rails/tree/master. I have been using this environment under emacs 23, and it has not been tested on other emacs versions, so all feedback is welcome, if something goes wrong please feel free to contact me.

What’s in the package?

The package provides my customized Emacs init file and some plugins I found very useful to enhance Ruby on Rails development experience.

Plugins

Installation

Before you can use some plugins you have to install a few packages:

To use rcodetools you need to install the rcodetools, gem with
sudo gem install rcodetools
To use autotest you need the ZenTest gem, install it with
sudo gem install ZenTest
On further post I’m going to explain how to set it up under the gnome environment using all the beauty that gnome-notifier has. Checkout the package
git clone github.com/spastorino/my_emacs_for_rails
and copy all the files under my_emacs_for_rails directory to ~/.emacs.d directory if it doesn’t exist you have to create it.

Screenshot

You can see here some screenshots to get a taste of the look and feel that this one has.

|

If you have found this material to be useful, you might
consider recommending me on Working With Rails.

sebastian.martinez

Scheduling in Ruby 5

Posted by sebastian.martinez
on Monday, August 10

Scheduling tasks is something we all need to know to do, for it’s quite common in applications. Fetching feeds, indexing some data, processing files at a periodical time, that happens a lot. You are probably quite familiar then with the linux cron, if you had to deal with scheduling stuff in the past, but there is something you may not. Let me introduce you the Whenever gem. What is it? A simple gem to schedule tasks writing them in nice ruby syntax…just let the gem work it’s magic and deal with the cron.

In order to install it, you have to add first the github source, only if you never done it :
$ gem sources -a http://gems.github.com
$ sudo gem install javan-whenever
To get started, just place yourself in the app path and type
$ wheneverize . 
This will create an initial config/schedule.rb for you.

There you can nicely write tasks to run.

Some examples are:
every 3.hours do
    runner "MyModel.some_process" 
    rake "my:rake:task" 
    command "/usr/bin/my_great_command" 
  end

  every 1.day, :at => '4:30 am' do
    runner "MyModel.task_to_run_at_four_thirty_in_the_morning" 
  end

  every :hour do # Many shortcuts available: :hour, :day, :month, :year, :reboot
    runner "SomeModel.ladeeda" 
  end

  every :sunday, :at => '12pm' do # Use any day of the week or :weekend, :weekday
    runner "Task.do_something_great" 
  end
Another nice thing to do is integrate it with Capistrano.

 after "deploy:symlink", "deploy:update_crontab" 

  namespace :deploy do
    desc "Update the crontab file" 
    task :update_crontab, :roles => :db do
      run "cd #{release_path} && whenever --update-crontab #{application}" 
    end
  end

The official documentation provides this way to integrate it, but we found some little details, and the solution is here for you.

If you integrate it by the regular way, when making multiple deploys, it will configure several tasks to run in your cron file. Why? Because the path of the current application changed, and the gem uses the path (by adding a comment line) when updating the cron. What should we do then? Simple, change the run line with this:
run "cd #{current_path}; whenever -i #{current_path}/config/schedule.rb" 

What have we done? We used the -i option, which makes an update, but passing the comment we want, and make it not to change in every deploy.

Feel free to try it and leave your comments !!

|

If you have found this material to be useful, you might
consider recommending me on Working With Rails.

jose.costa

Method missing to simplify queries to an external service 5

Posted by jose.costa
on Wednesday, August 05

I know there are several discussions on the usage of method_missing in Ruby. In this post i’ll present a pretty simple, yet useful solution that uses method_missing to interact with the Brightcove Media Read API (you don’t need to be familiar with this service, i’ll explain a little bit in the next few lines).

Brightcove Media Read API accepts calls of the form:

http://api.brightcove.com/services/library?command=find_all_videos
&token=0Z2dtxTdJAxtbZ-d0U7Bhio2V1Rhr5Iafl5FFtDPY8E.

http://api.brightcove.com/services/library?command=find_related_videos
&video_id=123123&token=0Z2dtxTdJAxtbZ-d0U7Bhio2V1Rhr5Iafl5FFtDPY8E.

http://api.brightcove.com/services/library?command=find_videos_by_text
&text=sometextsample&pageSize=100&token=0Z2dtxTdJAxtbZ-d0U7Bhio2V1Rhr5Iafl5FFtDPY8E.

A token must be passed on each call, and you could also add more parameters like you would do in a regular GET request. What comes back is a JSON string that can be easily picked up.

The key thing here is to notice that there are several commands you could execute from the API, naturally each with its own name that must be specified in the request right after “command=”. Since the API also provides a set of error codes to address all wrong requests or non-existent commands requests, we simply wanted to forward all the calls to the API and reply back with its answer. So, in order to avoid defining all API methods in our Ruby module, we just used the method_missing and forwarded all calls to it, using the name of the method as the API command.

The idea was that a call like:

http://api.brightcove.com/services/library?command=find_videos_by_user_id
&user_id=34876423&token=0Z2dtxTdJAxtbZ-d0U7Bhio2V1Rhr5Iafl5FFtDPY8E.

became just:

Brightcove::ReadProxy.find_videos_by_user_id :user_id => 34876423

We then implemented what we called the Brightcove::ReadProxy in a few lines like shown below:

module Brightcove
  module ReadProxy

    TOKEN = '0Z2dtxTdJAxtbZ-d0U7Bhio2V1Rhr5Iafl5FFtDPY8E.'
    SITE = 'http://api.brightcove.com/services/library'

    def self.method_missing(method_id, *args)
      args[0] ||= { }
      args[0].merge!({ :command => method_id, :token => TOKEN })
      get SITE, args[0]
    end

    def self.get(url, params)
      http_client = HTTPClient.new
      result = http_client.get(url, params)
      content = nil
      begin
        content = JSON.parse(result.content)
      rescue Exception => e
        Rails.logger.error e.message
      end
      return content
    end

 end

Basically all the magic relies in the method_missing that would convert any call to the Brightcove::ReadProxy module in the format accepted by the API, without having to define every API method and maintaining the Rails like finders syntax. We also used the httpclient gem to simplify the GET request calls and the json gem to parse the result of the call.

I’m not saying that this is the best usage, but i think in this particular situation it suits pretty well.

What do you think?

|

If you have found this material to be useful, you might
consider recommending me on Working With Rails.

sebastian.martinez

Drag & Drop Sortable Lists 0

Posted by sebastian.martinez
on Monday, July 27

Time has come for us to make a sortable list, and let’s face it, drag&drop are the prettiest ones. So, let me explain how to proceed.

Suppose you have a playlist with many videos, and want to establish an order on which they will be played. First thing you will need is to add a ‘position’ attribute to your Video model. To do that, we’ll generate a migration first:

script/generate migration add_position_to_videos position:integer

Now just run rake db:migrate.

View Code

First thing you need to make sure, is that you have the prototype and scriptaculous libraries in your application. Now let’s see how your index.html.erb file should look like
   <h1>Videos</h1>  
   <ul id="videos">  
     <% @videos.each do |video| %>  
       <% content_tag_for :li, video do %>  
         <%= link_to video.name, video_path(video) %>  
       <% end %>  
     <% end %>  
   </ul>  
   <%= link_to "New Video, new_video_path %>  

Now all we have to do to make the list sortable is add the sortable_element helper method to the index view. You need to pass it the id of the element you want to be sortable, and a URL that is called via an AJAX request so that the updated positions can be stored in the database.

   <%= sortable_element('videos', :url => 'sort_videos_path') %>  

The videos in the list can now be dragged and dropped, but the new order isn’t persisted back to the database. So let’s code the sort method in the videos_controller.rb

   def sort  
     params[:videos].each_with_index do |id, index|  
       Video.update_all([’position=?’, index+1], [’id=?’, id])  
     end  
     render :nothing => true  
   end  

And that’s it. We are now updating the position of the videos. Most probably, we would want now our videos to be shown in the index in the correct order, so we just need to touch the index method on the controller a bit.

   def index  
     @videos = Video.all(:order => ’position’)  
   end  

At this point we are almost set to go…did you guess what’s missing? Yes, we need to add the route to the sort method :)

   map.resources :videos, :collection => { :sort => :post}  

The line above adds the new action and makes it a POST request, which is the type that our AJAX call uses when making XMLHTTP requests. And that’s pretty much it. Now you have a fully functional sortable list of videos.

There are some more tricks we can use to improve this, for example, the sortable_element helper receives one option called ‘handle’. What’s this? The way to specify the draggable area of the element. This I think is the most used one. Let’s give it a try:

We should first add a span tag on the index view:
 <% content_tag_for :li, video do %>  
   <span class="handle">[drag]</span>  
   <%= link_to video.name, video_path(video) %>  
 <% end %> 

Note the span has a ‘handle’ class, and that’s what you are going to set as draggable, using the :handle option:

   <%= sortable_element(’videos’), :url => sort_videos_path, :handle => ’handle’ %>  
You can style this a bit with a CSS, adding a line similar to this one:
 li .handle { color: #777; cursor: move; font-size: 12px; } 

Beautiful….just beautiful…

Ok, we have this magical sortable list now, but we added a ‘position’ field to videos…we can handle this manually when creating or updating the videos, or we can use the acts_as_list plugin, which I recommend. Just install it by typing

script/plugin install git://github.com/rails/acts_as_list.git
in your console. All configuration this needs to work is to add acts_as_list in our model, that should look like this:

   class Video < ActiveRecord::Base  
     acts_as_list  
   end  

Congrats!!! Enjoy your sortable list !!!

|

If you have found this material to be useful, you might
consider recommending me on Working With Rails.

santiago.pastorino

Paperclip file rename 0

Posted by santiago.pastorino
on Tuesday, July 14

While developing an application with Sebastián that allow users to upload videos with some file name restrictions, meaning that it must contain only A-Z and 0-9 digits, underscores (_) as a valid component as well, and also the name must be preceded by it’s own #id, we came up with the need of applying this custom filter to each uploaded video. After doing some research on paperclip source code and internet tutorials, we suggest the following solution:

class Video < ActiveRecord::Base
  has_attached_file :video,
    :path => ":rails_root/public/system/:attachment/:id/:style/:normalized_video_file_name",
    :url => "/system/:attachment/:id/:style/:normalized_video_file_name" 

  Paperclip.interpolates :normalized_video_file_name do |attachment, style|
    attachment.instance.normalized_video_file_name
  end

  def normalized_video_file_name
    "#{self.id}-#{self.video_file_name.gsub( /[^a-zA-Z0-9_\.]/, '_')}" 
  end
end
What are we doing here? Easy, in has_attached_file we edit the way paperclip returns the path and url by default, the most relevant components when saving and loading the file in order to display it. Paperclip default values are:
path default => ":rails_root/public/system/:attachment/:id/:style/:filename" 
url default => "/system/:attachment/:id/:style/:filename"

Values preceded by ’:’ are the standard interpolations paperclip has. For further information on this visit http://wiki.github.com/thoughtbot/paperclip/interpolations.

What we did was change * with *:normalized_video_file_name in both path and url, being the second a custom interpolation and then added the ‘normalized_video_file_name’ method to video.rb.

By doing this we not only achieve a way for paperclip to handle the file by this normalized way, but also have a method to access the normalized file name, plus being able to access the original file name through paperclip video_file_name method.

So remember on video_file_name you have the uploaded filename and on normalized_video_file_name you have the server filename.

|

If you have found this material to be useful, you might
consider recommending me on Working With Rails.

martin.alcala

Is your product Innovative? 0

Posted by martin.alcala
on Monday, July 06

That’s a good question, in fact, can we quantify or measure how much “innovation” quantity exists in our product or services?. Well, there are as much answers as successful products ;-) but in general terms we can group Innovation in three categories:

  • Business Model

    Is your Business Model Innovative? did you find out a new way to sell? did you find out an hidden need of the community? Starbucks would be a nice example.

  • Tech

    Did you invent new super algorithm to ultra-fast classify all the info on the web ;-) – that a techy innovation -. Tech is a great point for innovation, but not the only one, think about twitter for example.

  • Design

    Design in fact is key a factor for innovation, for example think about the IPhone or the IPod, the key was the design and the marketing.

    So you reader, Rails Enthusiast, Ruby Rockstar, Code Ninja, are you ready to innovate in the wide sense or the word?

|
twitter-me
sebastian.martinez

Rails delegate method 4

Posted by sebastian.martinez
on Thursday, June 04

Delegation is a feature Rails introduced in it’s 2.2 version, and in my opinion are quite useful and somehow something we don’t see too much around. The concept of delegation is to take some methods and send them off to another object to be processed.

Let me explain this with a brief example:

Suppose you have a User class for anyone registered on your site, and a Customer class for those who have actually placed orders:

class User < ActiveRecord::Base  
   belongs_to :customer  
end  

class Customer < ActiveRecord::Base  
   has_one :user  
end

As for now, if you are in a Customer instance, you can get their User information doing @customer.user.name, or @customer.user.email. Delegation allows you to simplify this:

class User < ActiveRecord::Base  
   belongs_to :customer  
end  

class Customer < ActiveRecord::Base  
   has_one :user  
   delegate :name, :name=, :email, :email=, :to => :user  
end

Now you can refer to @customer.name and @customer.email to retrieve and set values for those attributes directly. Pretty nice, huh?

We are now working on some code to make possible to inherit behaviour, along with polymorphic associations, so when you create a Cutomer, the User gets created as well with the data you provided when creating the customer, and so on.

So keep posted, for there will be more to come…

|

If you have found this material to be useful, you might
consider recommending me on Working With Rails.

sebastian.martinez

We're attending Locos X Rails ! 0

Posted by sebastian.martinez
on Monday, March 30

We’re attending Locos X Rails conference !!!!

It will be held on April 3rd and 4th at Universidad de Palermo in Buenos Aires, Argentina.

Who are the speakers going to be? Obie Fernandez, Yehuda Katz, David Heinemeier Hansson (via teleconference), Luis Lavena, Fabio Akita, and many more! Does anyone sounds familiar?

It is with no doubt a great opportunity that we just couldn’t miss…

Hope to see you all there!

|

If you have found this material to be useful, you might
consider recommending me on Working With Rails.

sebastian.martinez

Setting up Passenger in Linux 0

Posted by sebastian.martinez
on Wednesday, January 28

Clearly one of the problems with Rails as a major platform right now is it’s hosting situation. Currently a good solution is to proxy HTTP requests from Apache or Nginx to a cluster of mongrels, which is tricky to set up and somewhat tedious. I wanted to easily have our rails applications deployed (in our development environment), and have them running without having to manually start each server. Messing around I found Passenger, a module for Apache that hosts Rails applications. Note this was tested in Ubuntu, but it’s very similar for other Linux distributions.

To install the module simply run:
$ sudo gem install passenger
Then, you need to do
$ passenger-install-apache2-module

and just follow the instructions. The installer is very easy to follow, and in my case it detected some software not installed, so i had to run

$ sudo apt-get install apache2-prefork-dev

Once the installation was successfully completed, it asked to add the following lines to the apache configuration file, /etc/apache2/apache2.conf

"LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.0.2/ext/apache2/mod_passenger.so
PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.0.2
PassengerRuby /usr/bin/ruby1.8" 

At this point, Passenger is properly configured, and the only thing left is to configure our applications to work with Apache. So, let’s do it: make your ‘httpd.conf’ file to look like this:

NameVirtualHost localhost:80
<VirtualHost localhost:80>
      ServerName app1.local
      DocumentRoot /app1_path/public
</VirtualHost>

<VirtualHost localhost:80>
      ServerName app2.local
      DocumentRoot /app2_path/public
</VirtualHost>
...and so on for more applications. Also, modify the ’/etc/hosts’ file to have your applications go to localhost. It should look similar to this:
127.0.0.1       localhost app1.local app2.local

There are some considerations to make here. First and most important, the rails environment. Passenger sets it to production as default, but if you want it to be some other, just need to add the following line into the configuration file:

RailsEnv environment

Now if you just type into your browser app1.local you should see your application alive! Without the images and style? Yes, simply to solve.

Delete the following file and restart apache.
$ rm -f /your_app_path/public/.htaccess

Bingo!

That was all the strictly necessary to have your application deployed with Passenger…but we have some tricks to share ;)

Suppose you want your Ruby on Rails application to be accessible from the URL http://localhost/app. To do this, make a symlink from your Ruby on Rails application’s public folder to a directory in the document root. For example:

Type

$ ln -s /your_app_path/public /var/www/app1

in a terminal.

Next, add a RailsBaseURI option to the virtual host configuration:


<VirtualHost localhost:80>
    ServerName app1.local
    DocumentRoot /app1_path/public
    RailsBaseURI /app1                # This line has been added.
</VirtualHost>

Now, according to Passenger’s documentation, this should be it, but I’ve found some problems with Rails 2.2.2. Going to http://localhost/app1 now may give you a HTTP 404 error. To solve this, you need to add this line to environment.rb of your application:

config.action_controller.relative_url_root = "/app1"

Another sweet thing is restarting a Rails app hosted by Passenger – simply touch a file called tmp/restart.txt within the Rails application root:

$ touch tmp/restart.txt

And that’s it. Enjoy this beauty. Note that this configuration is intended to be for development environment only. Passenger provides other parameters for production, which we will tackle in the near future, and public our opinions. So, don’t forget to keep visiting us. Seeya in the next post!

|

If you have found this material to be useful, you might
consider recommending me on Working With Rails.