A small snippet for testing.
If you want to add some special actions before and after the execution of each test, and don't want to add it to setup and teardown because you will be repeating your code for each unit test and functional test, or because it is a block, you can do an alias_method_chain for the run method:
module Test module Unit class TestCase def run_with_my_block(*args, &block) Cache.clean # code before a_block_that_you_want_to_execute do run_without_my_block(*args, &block) end # Code after end alias_method_chain :run, :my_block end end endYou can redefine it at the beginning of your test_helper.rb for example.
Note that this code is only for Rails, becaus of the use of alias_method_chain function.
Google Maps is, may be, the coolest service for integrating maps in your web applications: it offers a powerful and easy API with no limit usage.
The problem is that it loads quite Javascript that has to connect to the main Google Maps page in order to draw our map. In order to avoid that we can use static Google Maps, it is, a picture (generated in real time) of the map we want to visualize. The problem with this is that you can't interact with the map (because it is an image) and that there is a limitation per day. But may be you find it useful in a particular moment.
For example, in iwannagothere.net we have a small map in every place that shows the location of that city:
In that situation we can change the map because the map is not for navigating along the city. For that you have a map in each item.
In Ruby on Rails, the programming framework of iwannagothere.net there is a gem called static-gmaps that does the hard work for you. What's more, we have found the way to integrate this maps with attachment_fu, in order you save a copy of the map in your filesystem and then avoid the day limitation usage.
Basically we have an attachment_fu kind of model (nothing special here):
class PlaceMap < ActiveRecord::Base belongs_to :place has_attachment :content_type => :image, :storage => :file_system, :processor=> :rmagick, :path_prefix => 'public/userfiles/place_maps', :max_size => 1.megabyte validates_as_attachment endThe we generate the static map instance:
map = StaticGmaps::Map.new :center => [ place.lat, place.long ], :zoom => 12, :size => [ 334, 144 ], :key => APP['gmkey']And save it in our PlaceMap model:
PlaceMap.create(:uploaded_data => (open(map.url)), :place_id => place.id, :content_type => 'image/gif')The problem here is that we are not uploading a file in the usual way: we are trying to save a raw of data. Attachment_fu doesn't know how to do that, so we have to apply a little patch:
module Technoweenie module AttachmentFu module InstanceMethods def uploaded_data=(file_data) return nil if file_data.nil? || file_data.size == 0 self.content_type = file_data.content_type self.filename = Time.now.to_i.to_s+'.gif' if file_data.is_a?(StringIO) file_data.rewind self.temp_data = file_data.read else self.temp_path = file_data end end end end endHere we are giving a random filename, generated from the current time.
And that's all, really easy :)
iwannagothere.net is the last project from mamuso, Maria and me. It's a site about traveling with two main purposes:
It's a kind of independent and high quality information travel guide.
As in unvlog.com we developed it in Ruby on Rails, (now running version 2.1), in our free time, along 3 months. Now we are refining a lot of details, and adapting some parts that we have seen people don't use as we thought.
We are going to explain all the technical issues we had in a serie of small posts in this blog or in the iwannagothere's blog. As well, we are going to present it at Spanish Rails Conference 08 in November.
We hope you enjoy the site and find it useful.
I think that the moment has arrived. This blog switches to English (to my bad English, that surely all Spanish will understand), because this is the only way to participate in the conversation of the international community.
Muchas veces cuando trabajamos con ActiveRecord nos olvidamos / ignoramos qué hace por debajo.
Un claro ejemplo lo encontramos cuando tenemos una relación :has_many y queremos comprobar si un elemento está incluída en dicha relación.
Por ejemplo:
class Place class ItemSeguro que más de una vez, para comprobar que un place contiene un ítem hemos utilizado el "rubysta" include?:
place.items.include?(item)Pensándolo fríamente 0.2 segundos nos damos cuenta de que estamos cargando un array con todos los elementos de una relación, que pueden ser 10 o pueden ser 1.000.000. Y ya sabemos lo generoso que es Ruby con la memoria que toma y que nunca deja ir.
Un truco para evitar que esto suceda sin dejar de utilizar include? es definir dicho método dentro de la relación tal que así:
class Place ["item_id = ?", item.id]) > 0 end end endEs decir, resolvemos el problema con un simple COUNT de Mysql.
¿Alguien se anima a hacer un plugin? Creo que sería bastante inmediato para cuando se cumplen las convenciones y sabemos que la clave foránea de la relación es singular del nombre de la relación_id. O quizá ni eso, si encontramos la forma de preguntarle a ActiveRecord cuál es la clave foránea de una relación.
Cuando tienes una aplicación en producción es más que necesario controlar los tiempos de las peticiones más lentas.
Sin embargo muchas veces con el log de Rails no es suficiente, y hay que alcanzar un mayor nivel de detalle.
El log en modo debug nos da todo el detalle que necesitamos, pero mostrando demasiada información (¿de qué nos sirve saber que un SELECT sencillo tarda 0.001 segundos?).
Pero si en ese log pudiéramos filtrar las consultas SQL más lentas sí que tendríamos información de consultas lentas asociadas a cada petición al servidor.
Gracias al plugin query trace y a una pequeña modificación podemos mostrar qué consultas tardan más de 1 segundo:
module ActiveRecord module ConnectionAdapters class AbstractAdapter def log_info(sql, name, runtime) return unless @logger @logger.info( format_log_entry( "#{name.nil? ? "SQL" : name} (#{sprintf("%f", runtime)})", sql.gsub(/ +/, " ") ) ) if (RAILS_ENV == 'production' && runtime > 1.0) || RAILS_ENV != 'production' end end end endEste código lo he probado en Rails 1.2.x, no sé si funcionará en otras versiones.
Si trabajáis con control de versiones una de las operaciones más habituales es ver las modificaciones de un fichero. Eso en Subversion se hace con svn diff.
Sin embargo yo utilizo un script que creo que me pasó porras para que me muestre en colores las modificaciones.
El script es este:
#!/usr/bin/env ruby `svn diff #{ARGV.join(' ')}`.each do |line| puts( if line =~ /^\+(.*)$/ "\e[32m#{$&}\e[0m" elsif line =~ /^-(.*)$/ "\e[31m#{$&}\e[0m" else line end ) endCon darle permisos de ejecución ya podéis tener un svndiff por ejemplo.
No pongo el equivalente en git porque es bastante inmediato.