Bases De Datos 5
Borrar un Scaffold en Ruby on Rails
Hay veces en que las cosas no salen bien y hay que hacer rollback en la vida. Por suerte, tenemos el comando rake db:rollback para deshacer migraciones en Rails, Cuando usarlo? bueno, si nos equivocamos en el nombre del scaffold, nos quedó mal hecho o un sin fin de razones más por las que quisieras borrar un Scaffold en Ruby on Rails. En esta infografía te explico como borrar uno y no morir en el intento.
Hay otras formas de borrar un Scaffold, como por ejemplo hacer una nueva migración que destruya la tabla y borrar el scaffold a mano. pero es más trabajo.
Esta es la forma fácil y bonita:
Haciendo Un Pequeño Buscador En Ruby On Rails
Una pregunta que se repite harto en el curso de En1mes es cómo hacer un buscador con ruby on rails, aquí la respuesta:
Paso 1: Para entender como funciona vamos a hacer un pequeño ejercicio, creemos un proyecto nuevo y llamemoslo buscador.
Paso 2: Creemos un scaffold de un recurso, digamos que estamos haciendo un buscador para un blog, donde el recurso principal son los posts, así que ejecutemos la línea:
rails g scaffold post titulo:string contenido:text
Paso 3: Hay que entender el paso de parámetros en rails, estas pueden ser pasadas por get (a través de la url) o por Post a través de algún formulario o dentro de la sesión, en este caso vamos a trabajar con el método get.
En google cuando nosotros buscamos algo podemos ver que el valor que buscamos también aparece en la URL acompañado de un q=
Ruby on Rails nos permite hacer exactamente lo mismo, capturar los valores que vienen de la URL ocupando un diccionario llamado params que captura todos los valores que vienen en la URL (entre otras cosas), por ejemplo si nosotros quisiéramos capturar el mismo valor lo podemos hacer desde el controller de post, en el método index
def index @q = params[:q] @posts = Post.all end
Paso 4: Una vez que tenemos capturado el valor lo podemos mostrar en la vista de index de los posts.
<%= @q %>
Paso 5: El formulario
No podemos esperar que el usuario escribe el query a buscar en la URL, lo lógico es que haya un formulario de buscar, lo podríamos hacer con los helpers de Rails pero para mantener la simplicidad del tutorial lo vamos a hacer estilo html.
El formulario consiste simplemente en una etiqueta form y un input y un botón de envío (opcional) que vamos a poner en la vista index de los posts.
<form> <input name=”q” <%= @q %> > <button type=”submit”>Buscar</button> </form>
Paso 6: Filtrar los resultados
Lo único importante que está faltando es filtrar los resultados de los posts en base a la búsqueda, para eso tenemos que volver al controller de los posts y editar el método index.
def index @q = params[:q] if @q @posts = Post.where(:titulo => @q) else @posts = Post.all end end
Si quieren que continúe el post agregando cosas sobre como hacer match parciales y mejorando la búsqueda pueden presionarme por Twitter @gsanchezd ☺
Instalando PostgreSQL para Ruby on Rails en OSX
PostgreSQL es un excelente motor de bases de datos pero para los que estamos acostumbrados a las bondades de OSX de que todo sea una simple aplicación que se descarga y estamos listos puede ser frustrante.
Este error lo obtenemos cuando tenemos declarada la gema pg en el gemfile (aunque sea exclusivamente para el entorno de producción) y nosotros no la tenemos dentro de nuestro computador. Si no queremos ocupar la gema pg lo que podemos hacer es decirle a bundle que no la instale localmente, esto se puede lograr con:
bundle install --without production
Pero, ¿Qué pasa si realmente queremos instalar la gema para poder homologar el entorno de desarrollo con el entorno de producción, o, queremos descargar la base de datos de heroku (que está en Postgres) y ocuparla dentro de nuestro computador?
Instalando PostgresSQL
Paso 1: Descargar e instalar postgresAPP
Paso 2:
Agregar al path la carpeta de binarios Este paso es ligeramente más complejo, hay que abrir con sublime, vim, nano o el editor que quieras el archivo .bash_profile que se encuentra oculto en la carpeta de usuarios (todo los archivos que empiezan con un punto están ocultos en OSX y en Linux), ahí dentro tienes que agregar al final:
PATH="/Applications/Postgres.app/Contents/Versions/9.3/bin:$PATH"
Y con eso estaríamos listos, ahora tienes que abrir una nueva terminal (cada vez que modificas el path tienes que abrir una terminal nueva para que cargue, vas a la carpeta de tu proyecto rails y bundle install.
Te gustaría descargar la base de datos de Heroku para ocuparla localmente?, aquí los pasos para descargarla y usarla.
El problema de las n+1 queries en Ruby on Rails
El Active Record de Ruby on Rails tiene muchas cosas geniales, pero algunas de ellas si no las manejas bien pueden repercutir negativamente en el rendimiento de la aplicación.
Uno de los errores más frecuentes de los desarrolladores novatos de rails es el problema de las N+1 queries.
El problema sucede cuando intentando realizar una sola consulta a la base de datos termina haciendo N+1 consultas, y aunque cuando uno tiene una base de datos con pocos datos el efecto es casi invisible, a medida de que crece el número de datos y el número de clientes este problema puede llegar a impactar de forma muy dura en el rendimiento de tu aplicación a tal punto de botarla.
¿Cuándo ocurre?
El problema ocurre cuando se itera sobre los hijos de uno de los objetos del modelo, para analizarlo sobre un caso práctica imaginemos que tenemos 2 modelos, uno de usuario y el otro de pins y cada usuario tiene muchos pins.
Específicamente el problema se hace visible en la iteración de los resultados.
Ahora cuando uno trabaja bajo un paradigma MVC es raro que uno tenga el código de esta forma, lo más probable es que el llamado a todos los usuarios se haga en la página index y luego dentro de la vista usuario se itere sobre los resultados mostrando por ejemplo los 5 mejores pins de cada usuario, pero el resultado es exactamente el mismo, n+1 llamados a la base de datos.
Para este caso de pruebas se tienen 2 usuarios, Diego y Gonzalo y uno tiene 3 pins y el otro ninguno, y aquí podemos observar que que se hicieron 2 queries a la base de datos en lugar de solo 1.
Para solucionarlo en el mismo momento que hacemos el query debemos incluir a los hijos del modelo, en nuestro caso el query inicial debió haber sido.
User.all.includes(:pin)
De esta forma se hace una sola consulta a la base de datos, ahora repitamos el experimento anterior y comparemos resultados.