Ruby on Rails¶
Enlaces¶
- Ruby on Rails Tutorial
- Programming Ruby: The Pragmatic Programmer's Guide
- Why's (Poignant) Guide to Ruby
- Ruby User's Guide
- Try Ruby
- Aptana Studio (IDE)
- Ruby on Rails Screencasts :exclamation:
- Ruby on Rails Guides :exclamation:
- Ruby Tutorial
- Rails 3 para Windows y Linux Ubuntu (libro en español)
- Rails Examples and Tutorials
- Ruby QuickRef
- Rails Tutorial Sublime Text setup
- Metaprogramming in Ruby: It’s All About the Self
- Comprobación de entorno de ejecución en código :exclamation:
Performance Tunning¶
- Performance Tuning for Phusion Passenger (an Introduction) :exclamation:
- Phusion Corporate Blog - Tuning Phusion Passenger’s concurrency settings
- Production Rails Tuning with Passenger: PassengerMaxProcesses
- Passenger tuning for rails application
- Phusion Passenger users guide, Apache version - Resource control and optimization options
El lío del respond_with¶
- Bringing Merb's provides/display into Rails 3
- Embracing REST with mind, body and soul
- What's New in Edge Rails: Cleaner RESTful Controllers w/ respond_with
- Respond With An Explanation
Módulos interesantes¶
- Devise: Engine de autenticación/autorización
- Forem: Engine para implementar un foro
- carmen-rails: Seed con datos de los países y las regiones del mundo.
- RailsCasts #328 Twitter Bootstrap Basics
- Twitter Bootstrap Gem
- FasterCSV: Carga y generación de ficheros CSV hacia y desde tablas. Ejemplo de uso.
- Entity-Relationship Diagrams for Ruby on Rails: Obtiene el esquema de relación entre entidades de una aplicación en base al análisis de sus modelos.
Instalación en Ubuntu¶
Algunas guías¶
- How to install Ruby on Rails in Ubuntu 12.04 LTS
- Buena guía de
railsapps
sobre instalación de Ruby/Rails - Otra guía de
railsapps
sobre actualización
Procedimiento Ubuntu <=13.04¶
- Instalar los paquetes:
ruby
ruby-dev
libsqlite3-dev
libmysqlclient-dev
nodejs
nodejs-dev
- Instalar RubyGems bajándolo de aquí y siguiendo las instrucciones de instalación de esa misma página.
- Instalar Bundler:
sudo gem install bundler
- Instalación de Rails:
sudo gem install rails
- Instalar passenger (el propio instalador da instrucciones sobre los paquetes necesarios):
sudo gem install passenger
- Instalar el módulo en Apache:
sudo passenger-install-apache2-module
- Tal y como indica la salida del comando anterior, hay que habilitar el módulo recién instalado por medio de la configuración de Apache. Se puede hacer añadiendo los dos siguientes ficheros:
#/etc/apache2/mods-available/passenger.load
LoadModule passenger_module /usr/lib/ruby/gems/1.9.1/gems/passenger-3.0.19/ext/apache2/mod_passenger.so
#/etc/apache2/mods-available/passenger.conf
PassengerRoot /usr/lib/ruby/gems/1.9.1/gems/passenger-3.0.19
PassengerRuby /usr/bin/ruby1.9.1
(las rutas contenidas en los ficheros anteriores dependerán de la instalación; la salida del comando que instala el módulo nos indica los valores correctos).
Finalmente hay que habilitar el módulo:
$ sudo a2enmod passenger
Y reiniciamos Apache:
$ sudo service apache2 restart
Procedimiento Ubuntu >=13.10¶
- Instalar los paquetes:
ruby
ruby-dev
libsqlite3-dev
libmysqlclient-dev
nodejs
nodejs-dev
- Instalar RubyGems bajándolo de aquí y siguiendo las instrucciones de instalación de esa misma página.
- Instalar Bundler:
sudo gem install bundler
- Instalación de Rails:
sudo gem install rails
- Instalar passenger siguiendo esta guía. Recomienda instalarlo con los paquetes de la distribución. A continuación se indica un resumen de los pasos.
- Instalar la clave PGP del repositorio que vamos a añadir:
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 561F9B9CAC40B2F7
- Instalar el siguiente paquete:
apt-transport-https
- Crear el fichero
/etc/apt/sources.list.d/passenger.list
con el siguiente contenido:deb https://oss-binaries.phusionpassenger.com/apt/passenger saucy main
- Actualizar el repositorio e instalar el siguiente paquete:
libapache2-mod-passenger
Buenas prácticas¶
- Skinny Controller, Fat Model
- Nesting resources: Resources should never be nested more than 1 level deep.
Tips¶
Visibilidad de Helpers¶
Los métodos definidos en los módulos Helper (app/helpers/<controller>_helper.rb
) son visibles en las vistas por defecto. Para que estén disponibles en los controllers hay que hacer un include
. Si lo hacemos en el controller base (ApplicationController
) estará disponibles en todos los controllers dado que éstos heredan de ApplicationController
.
Mejora en rendimiento en Desarrollo¶
Rails 3.1 introdujo el concepto del asset pipeline. Desafortunadamente esto causa problemas de rendimiento en el entorno de desarrollo. Para mejorarlo se puede utilizar la tarea de precompilador siguiente:
$ bundle exec rake assets:precompile:nondigest
Esto provoca que los cambios en los ficheros asset no sean incluidos automáticamente cuando recargamos la página. Para forzar su refresco hay que volver a ejecutar el comando anterior.
Borrado de assets¶
Rails proporciona la siguiente tarea de precompilador que borrará el directorio public/assets
, cosa que puede resultar útil antes de un commit.
$ bundle exec rake assets:clean
Esta orden puede solucionar el problema con el font-awesome
, que en ocasiones se dibuja mal.
También puede merecer la pena incluir el directorio public/assets
en el fichero .gitignore
.
Actualización de paquetes¶
Comandos interesantes relacionados con las versiones de los paquetes y su gestión:
bundle outdated
: Informe de paquetes desactualizados.bundle outdated <paquete>
: Informa sobre el nivel de actualización de un paquete.bundle update
: Actualiza todos los paquetes.bundle update <paquete>
: Actualiza el paquete.
Muestra el mapa de rutas¶
$ bundle exec rake routes
Muestra todas las tareas¶
$ bundle exec rake -T
Instalación de gem¶
Tras la instalación de un gem generalmente hay que instalar y ejecutar las migraciones de base de datos con los siguientes comandos:
$ rake railties:install:migrations
$ rake db:migrate
Para instalar una versión específica de una gem hay que añadir el argumento --version
, como por ejemplo:
$ gem install --version '3.0.13' passenger
Activar modo debug¶
Instalar primero la gem debugger
:
$ sudo gem install debugger
Añadir al Gemfile lo siguiente (probablemente sólo sea necesario en el entorno de desarrollo):
1 2 3 |
|
Insertar en el código una llamada a debugger
en el punto del código donde queramos que se detenga la ejecución.
Finalmente para arrancar el servidor en modo debug:
$ bundle exec rails s --debugger
Lo anterior sirve para depurar sobre Webrick. Para hacerlo bajo Passenger seguir las instrucciones de este post (con la ayuda de este otro). De forma resumida consiste en ejecutar:
$ cd <app_root>
$ sudo gem install ruby-debug19
Generar un task con:
$ bundle exec rails g task myapplication restart
Añadir lo siguiente al final del fichero config/environments/development.rb
:
if File.exists?(File.join(RAILS_ROOT,'tmp', 'debug.txt'))
require 'ruby-debug'
Debugger.wait_connection = true
Debugger.start_remote
File.delete(File.join(RAILS_ROOT,'tmp', 'debug.txt'))
end
Ejecutar:
$ bundle exec rake myapplication:restart DEBUG=true
Y una vez que hagamos una request para que se reinicie la aplicación ejecutar:
$ rdebug -c
Generación de un modelo¶
El siguiente comando creará un modelo para una entidad además de la migration correspondiente en la base de datos:
$ bundle exec rails g model spree/product_layout name:string view:string description:text
Path Helpers¶
Dada la siguiente definición de resources anidados:
resources :magazines do
resources :ads
end
Alternativamente al uso de los path helpers habituales, cuando se pasa como argumento un objeto se puede dejar a Rails que decida automáticamente el path helper necesario, es decir las siguientes líneas serán equivalentes:
<%= link_to "Ad details", magazine_ad_path(@magazine, @ad) %>
<%= link_to "Ad details", url_for([@magazine, @ad]) %>
En helpers como link_to
podemos indicar simplemente los objetos:
<%= link_to "Ad details", [@magazine, @ad] %>
O si queremos enlazar directamente a la magazine
en lugar de un array pasaremos directamente el objeto padre:
<%= link_to "Magazine details", @magazine %>
Tareas en base de datos¶
db:create
: creates the database for the current envdb:create:all
: creates the databases for all envsdb:drop
: drops the database for the current envdb:drop:all
: drops the databases for all envsdb:migrate
: runs migrations for the current env that have not run yetdb:migrate:up
: runs one specific migrationdb:migrate:down
: rolls back one specific migrationdb:migrate:status
: shows current migration statusdb:migrate:rollback
: rolls back the last migrationdb:migrate:redo
: runs (db:migrate:down
db:migrate:up
) or (db:migrate:rollback
db:migrate
) depending on the specified migrationdb:migrate:reset
: runsdb:drop
db:create
db:migrate
db:forward
: advances the current schema version to the next onedb:seed
: (only) runs the db/seed.rb filedb:schema:load
: loads the schema into the current env's databasedb:schema:dump
: dumps the current env's schema (and seems to create the db aswell)db:setup
: runsdb:schema:load
db:seed
db:reset
: runsdb:drop
db:setup
Gestión del plural/singular¶
Cuando un modelo/recurso tenga un plural irregular, se puede gestionar manualmente por medio de un Inflector
. Consultar esta guía.
Relación entre modelos¶
Estos serían los pasos para establecer una relación 1:n entre dos modelos preexistentes. Se basa en este apartado de las Rails Guides.
Partimos de los modelos Spree::Product
de la gem spree_core
y el modelo Spree::ProductLayout
propio de nuestra aplicación. La relación será un belongs_to
de Product a ProductLayout, es decir un n:1. Empezamos añadiendo la relación al modelo Product. Como es una entidad de una gem lo haremos con un fichero decorator:
#app/models/spree/product_decorator.rb
Spree::Product.class_eval do
belongs_to :product_layout
end
A continuación generamos un migration para añadir el campo que establece la relación en la tabla que mantiene el modelo Product:
$ bundle exec rails g migration AddProductLayoutRelationToProducts
Ahora lo editamos para incorporar el campo:
#db/migrate/20130228153926_add_product_layout_relation_to_products.rb
class AddProductLayoutRelationToProducts < ActiveRecord::Migration
def change
change_table :spree_products do |t|
t.references :product_layout
end
end
end
Finalmente ejecutamos el migrate:
$ bundle exec rake db:migrate
Inspeccionar la definición de un método¶
Si queremos averiguar en qué módulo se encuentra definido un método ejecutamos en consola IRB lo siguiente:
puts Objeto.new.method(:metodo).source_location
o
puts Objeto.instance_method(:metodo).source_location
Sustituyendo "Objeto" y "metodo" por lo que corresponda. Fuente.
Si se trata de un helper partimos de helper
, por ejemplo:
helper.method(:tab).source_location
Listar gems instalados¶
$ gem list --local
Si queremos sólo las versiones de una gem, de rails
por ejemplo:
$ gem list --local rails
Generar el API de rails¶
Para tener en local la versión actualizada del API de rails:
$ rails new dummy_app
$ cd dummy_app
$ bundle exec rake doc:rails
Luego mover el subdirectorio doc/api/index.html
a donde nos interese y borrar la dummy_app.
RubyGems Documentation¶
Para visualizar la documentación de todas las gems instaladas en el sistema ejecutar:
$ gem server
Y abrir la dirección: http://localhost:8808
Problema con el encoding de algunas fuentes en UTF-8¶
Al incorporar el gem spree_sermepa se produjo el problema descrito aquí.
Hay varias formas de solucionarlo. Una es añadir:
if RUBY_VERSION =~ /1.9/
Encoding.default_external = Encoding::UTF_8
Encoding.default_internal = Encoding::UTF_8
end
en la parte superior del Gemfile.
Si se utiliza Passenger para servir la aplicación, otra opción es sustituir la siguiente variable del fichero /etc/apache2/envvars
:
1 |
|
por:
1 |
|
Downgrade de Rubygems¶
Tras actualizar a la versión 2.0.3 de Rubygems empecé a tener problemas a la hora de hacer bundle install
. Aunque me pedía el password de root luego se producían errores de permisos en los directorios donde se almacenan las gems. La solución fue volver a una versión anterior de Rubygems. En concreto la misma que había en ese momento en el servidor de DinaHosting, es decir la 1.8.23. Se hizo con el siguiente comando:
$ sudo gem update --system 1.8.23
Solución a error "Could not find rake-10.0.4 in any of the sources" con Passenger¶
En el alojamiento de DinaHosting, al ejecutar por primera vez una aplicación Ruby ejecutada con Passport, se produce el error siguiente:
1 |
|
Instalando las gemas en el home del usuario se soluciona el error:
$ bundle install --deployment
Esto instala las gem's en el directorio vendor/bundle
.
Especificar entorno¶
Para especificar el entorno en una tarea rake
añadir al final de la orden RAILS_ENV=<entorno>
. Por ejemplo para desarrollo:
$ bundle exec rake routes RAILS_ENV=development
Con el script rails
, depende. Si se quiere arrancar la consola añadir al final el entorno sin más. Por ejemplo para desarrollo:
$ bundle exec rails c development
Si se quiere arrancar el servidor Webrick añadir el entorno por medio de la opción -e
. Por ejemplo para desarrollo:
$ bundle exec rails s -e development
Desinstalación de todas las gems¶
Con el siguiente comando:
$ gem list | cut -d" " -f1 | xargs gem uninstall -aIx
Posteriormente habrá que volver a instalar Bundler y el resto de gems. Para ello:
$ sudo gem install bundler
$ cd <proyecto>
$ bundle install
Plurales/Singulares de resources¶
Recurso de tipo colección dentro de un namespace:
Elemento | Plural/Singular | Ejemplo |
---|---|---|
Tabla en base de datos | Plural | spree_posts |
Clase del modelo | Singular | Spree::Post |
Fichero del modelo | Singular | spree/post.rb |
Clase del controlador | Plural | Spree::PostsController |
Fichero del controlador | Plural | spree/posts_controller.rb |
rails generator | Singular | rails g resource spree/post title:string body:text |
Ruta en config/routes.rb | Plural | resources :posts |
Directorio en views | Plural | spree/posts |
Ejecutar una versión concreta de rails¶
Si tenemos instaladas varias versiones del gem de rails, para forzar que se utilice el script rails
de una versión concreta, pondremos la versión de la siguiente forma:
$ rails _3.2.13_ -v
De forma que si por ejemplo queremos generar un nuevo proyecto con la versión 3.2.13 haremos:
$ rails _3.2.13_ new nueva_app
Ejecutar una versión concreta de spree¶
Si tenemos instaladas varias versiones del gem de spree, para forzar que se utilice el script spree
de una versión concreta, pondremos la versión de la siguiente forma:
$ spree _1.3.3_ -v
De forma que si por ejemplo queremos hacer la instalación dentro de una aplicación rails nueva con la versión 1.3.3 de Spree haremos:
$ spree _1.3.3_ install
Diagramas ERD¶
A continuación se indica el comando para obtener una serie de diagramas ERD interesantes. La documentación de todos los parámetros de ERD está aquí.
Modelado de producto en Spree:
$ bundle exec rake erd attributes=foreign_keys only="Spree::Product,Spree::OptionType,Spree::OptionValue,Spree::Variant,Spree::ProductOptionType" title='Productos'