Seguridad en aplicaciones Rails

9 de Mayo, 2008 — Ruby on Rails, SeguridadComentarios (0)

Os dejó algunos enlaces interesantes sobre seguridad en aplicaciones Ruby on Rails

www.rorsecurity.info/ruby-on-rails-security-cheatsheet/

www.rorsecurity.info/

wiki.rubyonrails.org/rails/pages/SecurityConcerns

Recortar imágenes con RMagick y attachment_fu

10 de Abril, 2008 — Ruby on RailsComentarios (1)

Attachment_fu no está preparado para realizar crop de imágenes, así que tendremos que hacerle una pequeña modificación para disponer de esta funcionalidad. Editamos el archivo rmagick_processor.rb, ubicado en el directorio processors, dentro de los archivos del plugin, y cambiamos el siguiente método:

# Performs the actual resizing operation for a thumbnail
def resize_image(img, size)
size = size.first if size.is_a?(Array) && size.length == 1 && !size.first.is_a?(Fixnum)
if size.is_a?(Fixnum) || (size.is_a?(Array) && size.first.is_a?(Fixnum))
size = [size, size] if size.is_a?(Fixnum)
img.crop_resized!(*size)
else
img.change_geometry(size.to_s) { |cols, rows, image| image.crop_resized!(cols, rows) }
end
self.temp_path = write_to_temp_file(img.to_blob)
end

Ahora cuando configuremos los atributos de la imágen en el modelo correspodiente, podemos hacer esto:

has_attachment :content_type => :image,
:storage => :file_system,
:max_size => 500.kilobytes,
:resize_to => '400>',
:thumbnails => { :cropped => ‘50×50!’ }

Formateo de fechas en Ruby on Rails

18 de Marzo, 2008 — Ruby on RailsComentarios (2)

18-3-2008: Actualizado para Rails 2

Una manera fácil de dar el formato que más nos guste a las fechas es hacerlo una a una utilizando strftime:

<%= post.created_at.strftime("%d-%m-%Y") %>

Eso esta muy bien para formatear un par de fechas, pero para toda una aplicación hay que encontrar un método de hacerlo automáticamente. Para eso creamos un archivo en el directorio config/initializers/ que formaterá las fechas de nuestra aplicación, le podemos poner el nombre que más nos guste, yo siempre utilizo date_format.rb y añadimos:

ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS[:default]='%d-%m-%Y %H:%m'

Con esto convertiremos todas las fechas que aparezcan en las vistas al formato “03-11-2008 22:34″

Si necesitamos varios formatos de fecha podemos hacerlo de la siguiente manera:

ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS.merge!(
:default => >%d.%m.%Y',
:my_format_1 => '%d/%m/%Y - %H:%M',
:my_format_2 => '%l:%M %p, %B %d, %Y',
:my_format_3 => '%d/%m/%Y')

:default es la manera por defecto como se mostrarán las fechas. Las variables my_format_x indican diferentes maneras que utilizaremos para formatear las fechas. Una vez hecho esto, cuando queramos escribir una fecha, lo haremos de la siguiente manera: supongamos un modelo u objeto llamado “Evento”, que en la tabla tiene un campo que se llama “fecha” de tipo DATE, para ver la fecha correctamente escribiremos:

<%=h Evento.fecha.to_s(:my_format_3) %>

Si el campo es DATETIME podemos utilizar el formato 1

<%=h Evento.fecha.to_s(:my_format_1) %>

Si no especificamos nada, utilizará el formato definido en :default

Así­ de fácil!

Cargando fixtures en la base de datos

9 de Febrero, 2008 — Ruby on RailsComentarios (0)

Cómo cargar las fixtures en el entorno en el que nos encontramos

rake db:fixtures:load

Cómo cargar las fixtures en un entorno diferente al que nos encontramos

rake db:fixtures:load RAILS_ENV=development
rake db:fixtures:load RAILS_ENV=test
rake db:fixtures:load RAILS_ENV=production

Cómo cargar sólo unas determinadas fixtures en la base de datos

rake db:fixtures:load FIXTURES=users,products

Palabras reservadas en Ruby on Rails

7 de Febrero, 2008 — Ruby on RailsComentarios (2)

Esta es la lista de palabras que no puedes utilizar ya que están reservadas por Ruby o Ruby on Rails. Vale la pena tenerla a mano, te ahorrarás algún cabreo que otro.

(más…)

Conclusiones después de la Conferencia Rails

27 de Noviembre, 2007 — Ruby on RailsComentarios (2)
  • Usa Nginx y Mongrel
  • Crea tus propios plugins que implementen las tareas que más se repiten en tus aplicaciones
  • Empieza a mirarte REST
  • Cuida la seguridad en tus aplicaciones, puedes tener un susto
  • Hay futuro en España para las aplicaciones ASP
  • Xavier Noria es un crack

¿Me dejo alguna?

Paginación a medida en Rails

14 de Septiembre, 2007 — Ruby on RailsComentarios (1)

Hace un tiempo me encontré con un problema que me costó un poco de trabajo solucionar. Necesitaba hacer un listado paginado, pero para poder ordenarlo era necesario hacer un JOIN de dos tablas. Al final lo he solucionado implementando un método que pagina una consulta SQL pasada como parámetro. El código de la función es el siguiente:

def paginate_from_sql(model, sql_query, total, per_page)
@pages = Paginator.new self, total, per_page, @params[’page’]
@items = model.find_by_sql(sql_query + ” LIMIT #{per_page} ” + “OFFSET #{@object_pages.current.to_sql[1]}”)
return [@pages, @items]
end

Lo he colocado en el application.rb para tener acceso desde cualquier controlador.

Para hacer el listado de una clase llamada Relation, llamo a la función de la siguiente manera:

def list
@relation_pages, @relations = paginate_from_sql(Relation,”SELECT * FROM articles RIGHT JOIN relations ON articles.id=relations.article_id ORDER BY articles.name ASC”,Relation.count, 50)
end

Yo he echo un JOIN de dos tablas, pero no hace falta decir que podeis poner la consulta SQL que necesiteis.

Formulario de contacto en RoR con Action Mailer

7 de Agosto, 2007 — Ruby on RailsComentarios (10)

Edito y amplío este post del 12 de diciembre del 2006 para intentar que el ejemplo sea más claro. Está probado en Rails 1.2.

localhost:~ User$ ./script/generate mailer Contact

Añadir al final del archivo config/environment.rb lo siguiente para que Action Mailer pueda autentificarse y enviar el correo.

ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
:address => 'smtp.website.com',
:port => 25,
:authentication => :login, # Don't change this one.
:user_name => "smtp_username",
:password => "smtp_password"}
ActionMailer::Base.perform_deliveries = true
ActionMailer::Base.raise_delivery_errors = true
ActionMailer::Base.default_charset = "utf-8"

Se puede enviar también utilizando sendmail poniendo únicamente
ActionMailer::Base.delivery_method = :sendmail

Ahora edita el archivo app/models/contact.rb y añade el método que enviará el email:

class Contact < ActionMailer::Base
def contact_email(email_params, sent_at = Time.now)
@recipients = "contact@website.co.uk" # Dirección donde se envía el correo
@from = email_params[:name] + " <" + email_params[:address] + ">"
@subject = email_params[:subject]
@sent_on = sent_at
@body["email_body"] = email_params[:body]
@body["email_name"] = email_params[:name]
end
end

En el directorio ‘views/contact’ crea el archivo contact_email.rhtml, este archivo es el contenido del email que se enviará a la dirección especificada anteriormente. En este caso se envían las variables “name” y “body”. Dentro de este archivo se puede poner texto y otras variables o incluso definirlo como html con las cabeceras correspondientes.

Name:
<%= @email_name %>
Message:
<%= @email_body %>

Vamos a crear el formulario de contacto. Crea una vista en el controlador principal, por ejemplo contacto.rhtml:

<%= start_form_tag :action=> "send_mail" %>
<label for="email_name">Name:</label>
<%= text_field "email", "name", :size => 30 %>
<label for="email_address">Email Address:</label>
<%= text_field "email", "address", :size => 30 %>
<label for="email_subject">Subject:</label>
<%= text_field "email", "subject", :size => 30 %>
<label for="email_body">Body:</label>
<%= text_area "email", "body", :rows => 8, :cols => 30 %>
<input value="Send Email" class="primary" type="submit" />
<%= end_form_tag %>

En el controlador principal añade el método siguiente que es el que procesa el formulario

def send_mail
Contact::deliver_contact_email(@params[:email])
end

Hay un detalle importante: el nombre del método que se llama es deliver_contact_email, en el modelo el método se llama contact_email. Cuando se llama a un método que envía un email con ActionMailer hay que seguir esta convención y añadir “deliver” antes del nombre del método.
Siguiendo este ejemplo podemos tener otro método que envía otro email que se llame contact_email_factory. Cuando lo invoquemos desde el controlador habrá que hacerlo con Contact::deliver_contact_email_factory(@params[:email])

Sólo nos queda añadir un enlace para poder acceder al formulario. En la página que queramos ponemos el siguiente enlace:

<%= link_to 'Contacto', :controller => "controlador_principal", :action => "contacto" %>

En el controlador principal tiene que haber un método cómo este que es el que procesa el enlace y muestra la vista correspondiente:

def contacto
render :action => 'contacto'
end

Configuración personalizada de dominios en Plesk con vhost.conf

22 de Junio, 2007 — Ruby on RailsComentarios (0)

Si queremos cambiar la configuración de un dominio podemos editar el archivo /var/www/vhosts/dominio.com/conf/hhtpd.include y modificar la configuración que crea Plesk por defecto. Este método tiene un problema: si modificamos la configuración a través de Plesk, volverá a reescribir este archivo y eliminará las modificaciones que hayamos realizado.
Para que las modificaciones sean permanentes debemos crear un archivo llamado vhost.conf en el mismo directorio donde está el httpd.include y añadir:

ServerAlias dominio.com www.dominio.com

y a continuación las modificaciones que deseamos realizar sobre el archivo httpd.include. Plesk “sobreescribirá” los valores de httpd.include con los que encuentre en vhosts.cof. Veamos un ejemplo:

httpd.include

<VirtualHost xx.xx.xx.xx:80>
ServerName dominio.com:80
ServerAlias www.dominio.com
UseCanonicalName Off
SuexecUserGroup dominio psacln
ServerAdmin admin@dominio.com
DocumentRoot /var/www/vhosts/dominio.com/httpsdocs
CustomLog /var/www/vhosts/dominio.com/statistics/logs/access_ssl_log plesklog
ErrorLog /var/www/vhosts/dominio.com/statistics/logs/error_ssl_log
</VirtualHost>

vhost.conf

ServerAlias dominio.com www.dominio.com
ServerAdmin pepe@otrodominio.com
Alias /estadisticas /var/www/vhosts/dominio.com/estadisticas

De esta manera sobreescribimos el valor de ServerAdmin y añadimos un valor nuevo que no estaba en httpd.include, Alias /estadisticas /var/www/vhosts/dominio.com/estadisticas

Para finalizar ejecutamos

/opt/psa/admin/bin/websrvmng –reconfigure-vhost –vhost-name=dominio.com -a -v

Utilizando vhost.conf para ejecutar aplicaciones Rails
Todo esto viene de la mala experiencia que he tenido con Plesk y Rails. Hace poco tuvimos unos problemas en el servidor que aloja los proyectos realizados en RoR. Uno de los comandos que se ejecutan en Plesk para realizar reparaciones, devuelve todos los archivos httpd.include a su estado original, por tanto las aplicaciones realizadas en Rails dejaron de funcionar.
Hasta ahora cuando quería subir un proyecto en Rails, colocaba todos los archivos en el directorio httpdocs y cambiaba los siguientes valores del archivo httpd.include

DocumentRoot /var/www/vhosts/dominio.com/httpdocs

por

DocumentRoot /var/www/vhosts/dominio.com/httpdocs/public

y

<Directory /var/www/vhosts/dominio.com/httpdocs>

por

<Directory /var/www/vhosts/dominio.com/httpdocs/public>

Para que los cambios sean persistentes podemos crear un archivo vhost.conf y colocar lo siguiente

ServerAlias dominio.com www.dominio.com
DocumentRoot /var/www/vhosts/dominio.com/httpdocs/public

ejecutamos

/opt/psa/admin/bin/websrvmng –reconfigure-vhost –vhost-name=dominio.com -a -v

y listo. Cuando realicemos cualquier cambio en la configuración del dominio nos mantendrá lo que haya en vhost.conf y todo continuará funcionando.

Autocompletado de campos en Ruby on Rails

9 de Mayo, 2007 — Ruby on RailsComentarios (0)

Después de muchas pruebas he conseguido implementar el autocompletado en Ruby on Rails. Os explico:
Lo primero es incluir en el layout las librerias javascript necesarias

<%= javascript_include_tag “prototype”, “effects”, “controls” %>

En la vista se crea un campo autocomplete tal que así­

<%= text_field_with_auto_complete :cliente, :poblacion, { :size => 25 }, :skip_style => true -%>

Ahora es necesario crear en el controlador un método como éste

def auto_complete_for_cliente_poblacion
search = params[:cliente][:poblacion]
param= search.downcase + ‘%’
find_options= {:conditions => [ ‘LOWER(poblacion) LIKE ?’, param ], :order => ‘poblacion ASC’, :limit => 5, :group => “poblacion”}
@clientes = Cliente.find(:all, find_options)
render :partial => “autoupdate_poblacion”
end

Y por último creamos el partial _autoupdate_poblacion.rhtml y añadimos lo siguiente

< ul class="autocomplete_list">
<% for cliente in @clientes.to_a -%>
< li class="autocomplete_item"><%= cliente.poblacion %>< /li>
<% end -%>
< /ul>

Si quereis darle un poco de formato añadís al css las clases autocomplete_list y autocomplete_item.

Entradas siguientes »
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 2.5 License. | Emili Parreño