Seguridad en aplicaciones Rails
Os dejó algunos enlaces interesantes sobre seguridad en aplicaciones Ruby on Rails
Os dejó algunos enlaces interesantes sobre seguridad en aplicaciones Ruby on Rails
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!’ }
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!
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
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.
¿Me dejo alguna?
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:
Yo he echo un JOIN de dos tablas, pero no hace falta decir que podeis poner la consulta SQL que necesiteis.
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
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:
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
vhost.conf
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
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
ejecutamos
y listo. Cuando realicemos cualquier cambio en la configuración del dominio nos mantendrá lo que haya en vhost.conf y todo continuará funcionando.
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
En la vista se crea un campo autocomplete tal que así
Ahora es necesario crear en el controlador un método como éste
Y por último creamos el partial _autoupdate_poblacion.rhtml y añadimos lo siguiente
Si quereis darle un poco de formato añadís al css las clases autocomplete_list y autocomplete_item.