Iloo

https://iloo.wordpress.com

Archivos por Etiqueta: ror

Ruby on Rails: puma en producción con SSL

Los detalles:

Servidor de producción: Centos 7

Servidor web: Apache 2.4.6

Ruby: 2.4.2

Esta guía es un compendio de varias guías que se pueden encontrar en internet.

Assets

Este archivo es importante para poder cargar los assets.

#/etc/httpd/conf.d/puma.conf

RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RequestHeader unset X-Forwarded-Proto
<locationmatch "^/assets/.*$">
	Header unset ETag
	FileETag None
	ExpiresActive On
	ExpiresDefault "access plus 1 year"
</locationmatch>

<locationmatch "^/assets/.*\.(css|js)$">
	RewriteEngine on
	RewriteCond %{HTTP:Accept-Encoding} \b(x-)?gzip\b
	RewriteCond %{REQUEST_FILENAME}.gz -s
	RewriteRule ^(.+)$ $1.gz
</locationmatch>

<locationmatch "^/assets/.*\.css\.gz$">
	ForceType text/css
	Header set Content-Encoding gzip
	Header add Vary Accept-Encoding
</locationmatch>

<locationmatch "^/assets/.*\.js\.gz$">
	ForceType application/javascript
	Header set Content-Encoding gzip
	Header add Vary Accept-Encoding
</locationmatch>

AddOutputFilterByType DEFLATE text/html

Apache

Configuramos el archivo /etc/httpd/conf/httpd.conf:

<VirtualHost 111.222.333.444:80>
ServerName puma.web.com
DocumentRoot /home/puma/public_html/puma/public

include /etc/httpd/conf.d/puma.conf
Redirect permanent / https://puma.web.com/

<Directory /home/puma/public_html/puma/public>
AllowOverride All Options=FollowSymLinks,MultiViews
Order deny,allow
Allow from all
</Directory>
</VirtualHost>


<VirtualHost 111.222.333.444:443>
ServerName puma.web.com
DocumentRoot /home/puma/public_html/puma/public

include /etc/httpd/conf.d/puma.conf
RewriteRule ^/(.*)$ https://0.0.0.0:9294%{REQUEST_URI} [P]

<Directory /home/puma/public_html/puma/public>
AllowOverride All Options=FollowSymLinks,MultiViews
Order deny,allow
Allow from all
</Directory>

SSLProxyEngine On
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off

SSLEngine on
SSLCertificateFile /home/puma/public_html/puma/FILE.cert
SSLCertificateKeyFile /home/puma/public_html/puma/FILE.key
SSLProtocol +TLSv1.2
SSLCACertificateFile /home/puma/public_html/puma/FILE.crt
</VirtualHost>

Puma

Se tiene que iniciar usando dos puertos uno para http y el otro para https, de la siguiente manera:

puma -d -b "ssl://127.0.0.1:9294?key=FILE.key&cert=FILE.cert&verify_mode=none&ca=FILE.crt" -b "tcp://127.0.0.1:9293" -e production

Cambiando los nombres de los archivo FILE.* por los de su certificado

Los puertos pueden ser cualquiera que no estén siendo usandos, podrían ser el 3000 y 3001 no hay problema.

 

 

 

 

Ruby on Rails: Simple Form, remover opción nula

Explicando un poco lo que sucede, si bien se tiene una colección de registro en un arreglo por ejemplo:

options = ["option1", "option2", "option3"].

Luego se genera el elemento en la vista:

= f.input :options_selected, as: :select, include_blank: false, collection: options, input_html: {multiple: true}

Si los elementos seleccionados son option1 y option3, la manera en que se almacena es:

["", "option1", "option3"]

Aun cuando se incluyo la opción include_blank se tiene un elemento nulo. Para solucionar esto es necesario agregar una opción mas, include_hidden, y el elemento seria:

= f.input :options_selected, as: :select, include_blank: false, include_hidden: false, collection: options, input_html: {multiple: true}

Y cuando se guarden las mismas opciones se almacenara sin el elemento nulo:

["option1", "option3"]

Ruby on Rails: turbolinks + growlyflash = no flash messages

Ruby_on_Rails_logo

Acabo de descubrir growlyflash, una excelente gema que básicamente muestra notificaciones emergentes a partir de los mensajes flash, estilo growl (mac).

Demo.

Todo bien hasta usar turbolinks, que evita recargar toda la página, y por tanto las notificaciones dejan de funcionar.

Para poder solucionar este detalle solo es necesario modificar el tag body (usualmente en application.haml o application.erb) de la siguiente manera, en haml:

%body(data-no-turbolink = '')

Ruby on Rails: PG::UndefinedTable: ERROR: relation “roles” does not exist

Ruby_on_Rails_logo

Usando Rails 4.1.1, siguiendo los pasos de configuración de rolify, se indica que es necesario ejecutar lo siguiente para generar los roles:

rails g rolify Role User

Todo bien hasta el momento de ejecutar la migración:

rake db:migrate

El mensaje de error es el siguiente:

PG::UndefinedTable: ERROR: relation “roles” does not exist

En mi caso, el generador creó el archivo:

20140520150218_rolify_create_roles

Claramente le faltaba la extensión .rb, agregando la extensión:

20140520150218_rolify_create_roles.rb

Y la migración sin problemas.

Ruby on Rails: descargar archivos desde Amazon S3

Con el trabajo, clases y entrenamientos (si también practico deportes), no puedo escribir tanto como quisiera, pero vamos haciendo la lucha.

Caso de estudio:

  • Aplicación alojada en Heroku, por tanto no se pueden subir archivos al servidor, se tienen que subir a Amazon S3.
  • Para subir los archivos se uso CarrierWave.
  • Se desea descargar los archivos alojados en Amazon S3 desde la aplicación en cuestión.

Vamos primero, instalando la gema necesaria, en el archivo Gemfile:

gem 'aws-s3'

Luego el bundle:

bundle install

En app/config/initializers se crea un archivo, en este caso aws_credentials.rb, con el siguiente contenido:

AWS::S3::Base.establish_connection!(
 :access_key_id => 'your_key_id',
 :secret_access_key => 'your_secret_key'
)

Suponiendo que se tiene un controlador files_controller.rb, y un modelo file.rb, se agregala función en cuestion para descargar el archivo

def download
 file = Files.find(params[:id])
 filename = file.filename.to_s.split('?').first.split('/').last
 aws_path = 'uploads/' + filename
 aws_object = AWS::S3::S3Object.find aws_path, 'bucket'
 send_data(aws_object.value, :filename => filename,:disposition => 'attachment') 
end

Debido a CarrierWave, file.filename, devuelve toda la url del archivo alojado en Amazon S3, es por que se esta usando el split, para obtener solo el nombre del archivo y almacenarlo en la variable filename.

Dependiendo como se haya configurado el uploader de CarrierWave se debe modificar lo que se esta almacenando en la variable aws_path, es la ruta donde se encuentra el archivo en Amazon S3.

En aws_object se tiene la ruta completa del archivo y se especifica el bucket donde se encuentra el archivo.

Finalmente se envía el archivo con send_data.

Por último se debe agregar la acción al archivo routes:

get :download, :on => :collection