También el uso de HAML, SASS, Bootstrap, y Twitter OmniAuth ...
Antes de empezar - Aquí está el código de GitHub para esta aplicación...
Recientemente tuvimos nuestra tercera conferencia Couchbase San Francisco que, por cierto, fue un gran éxito y un fantástico día / noche. En la conferencia, di una sesión de 80 minutos basada en la misma aplicación de ejemplo que vamos a construir hoy. El propósito de mi charla fue mostrar cómo podemos modelar documentos JSON dentro de Couchbase y utilizar todas las capacidades de Map/Reduce para construir una aplicación de extremo a extremo.
Este blog asume conocimientos de Rails y cierto uso del Portal del Desarrollador de Twitter. Si no has usado Couchbase o la gema Couchbase-Model antes, no te preocupes, te guiaré en esa parte, pero merece la pena leerlo. Modelo Couchbase ¡primero!
La idea general detrás de esta aplicación es que los usuarios puedan publicar sus propios vídeos Vine, para ser votados por el público para ver quién tiene los vídeos Vine más divertidos a nivel mundial. Los usuarios deben ser autenticados antes de enviar un Vine, y tenemos que hacer un seguimiento de qué Vine pertenece a qué usuario por medio de ID de referencia. es decir, cada Vine debe tener un User_ID dentro de su documento JSON, para que sepamos a quién pertenece.
Así que sin más dilación, vamos a ver cómo podemos construir una aplicación gamificada sobre Couchbase usando Ruby y Rails. La idea de tener una aplicación social con una tabla de clasificación y un elemento competitivo es un caso de uso muy común, pero no necesariamente uno que haya sido bien documentado (¡especialmente para nosotros en la comunidad Ruby!) Ahora bien, basta de cháchara, ¡vamos!
Requisitos previos:
- Servidor Couchbase 2.0+
- Ruby 1.9.3+
- Rails 3+
En lugar de publicar aquí cada una de las gemas de nuestra aplicación Rails, simplemente pulse aquí para ver mi Gemfile para ver que Ruby Gems necesitamos empaquetar para nuestra aplicación.
1 nota a hacer aquí es mi elección de servidor Ruby. Utilizo Puma. Esto no es necesariamente un beneficio en este pequeño caso de uso, es más un hábito personal. Puma es un servidor web concurrente para Ruby que arranca en el puerto :9292 por defecto. Puedes usar cualquier servidor web con el que te sientas cómodo, y simplemente iniciar tu aplicación con 'rails s' o 'rails server'.
Ahora, antes de empezar con nuestro código, vamos a crear un bucket en nuestra instancia de Couchbase llamado 'rvine'. No es necesario preocuparse por el tamaño de este bucket, así que dependiendo de la cantidad de RAM que tengas asignada a tu clúster, simplemente dale 200mb más o menos.
Así que vamos a generar una nueva aplicación Rails. Vamos a añadir a nuestro comando habitual la bandera '-O'. Esto es para omitir active_record includes. (No podemos usar active_record con Couchbase, pero para eso tenemos la gema Couchbase-Model).
Rails nuevo rvine -O
Ahora asegurémonos de que hemos copiado el Gemfile del repositorio enlazado arriba. La importancia de esto es asegurarnos de que tenemos tanto Couchbase como Modelo Couchbase incluido. Couchbase-Model es una abstracción sobre la gema Couchbase que permite patrones de diseño similares a Active-Record. Nos facilita enormemente el trabajo con Rails y Couchbase. Asegúrate de hacer clic en el enlace anterior y leer los detalles de la gema para obtener más información.
Cuando sepamos que tenemos ambas gemas en nuestro Gemfile, ejecutamos 'bundle install'. Una vez hecho esto, configuramos nuestra aplicación rails con Couchbase como backend. Desde tu directorio rails en Terminal, ejecuta el comando:
Rails genera couchbase:config
Esto generará un archivo couchbase.yml en nuestro directorio de configuración que enlaza nuestra aplicación con nuestra base de datos. Sigue adelante y edita ese archivo, e introduce las credenciales de nuestro bucket. Su archivo de configuración debe reflejar esto:
nombre de host: localhost
puerto: 8091
nombre de usuario:
contraseña:
piscina: defaultdevelopment:
< bucket: rvine
prueba:
< bucket: rvine
# establezca estas variables de entorno en su servidor de producción
producción:
nombre de host: <%= ENV[COUCHBASE_HOST] %>
puerto: <%= ENV[PUERTO_BASE_COUCH] %>
nombre de usuario: <%= ENV[COUCHBASE_USERNAME] %>
contraseña: <%= ENV[COUCHBASE_PASSWORD] %>
piscina: <%= ENV['COUCHBASE_POOL'] %>
cubo: <%= ENV[COUCHBASE_BUCKET] %>
Bien, una vez hecho esto, deberíamos tener un proyecto Rails barebone conectado a Couchbase como almacén de datos backend. ¿Parece sencillo? Pues porque Couchbase-Model nos hace la vida 1000 veces más fácil a la hora de modelar datos.
Ahora, lo siguiente que tenemos que hacer es configurar nuestro Clases de usuario y autenticación.
Vamos a crear nuestro modelo de usuario en primer lugar. Crea el archivo /app/models/user.rb
clase Usuario < Couchbase::Modelo
atributo :nombre
atributo :twit_username
atributo :avatar
def auto.find_or_create_from_auth_hash(hash)
usuario = Usuario.buscar_por_id(hash[:uid])
a menos que usuario
usuario = Usuario.crear!(:id => hash[:uid],
:nombre => hash[:info][:nombre],
:twit_username => hash[:info][:apodo],
:avatar => hash[:info][:imagen])
fin
usuario
fin
fin
En atributos en este documento son los campos que deseamos incluir en nuestro documento JSON. Estamos recogiendo el nombre del usuario, nombre de usuario de Twitter y Avatar. Necesitamos dar una clave única a cada usuario en nuestra base de datos. En este caso, lo estamos haciendo mediante la recopilación de Twitter UID del usuario y la creación de un hash de que para generar una clave para nuestro documento de usuario. Es importante recordar que la clave de cada documento en nuestra base de datos debe ser única. También, vale la pena señalar la clase que hemos creado. Esta clase hace exactamente lo que dice en la lata. Si un usuario existe, lo autentica. Si no, crearlos a partir de los datos de Twitter que recibimos.
Habrás notado que hemos elegido usar Twitter-Omniauth para esto, ¡para ahorrarnos un montón de tiempo en lugar de escribir una clase Auth desde cero! Lo primero que hay que hacer es ir a Twitter Dev y coger algunas claves de aplicación. Si nunca has hecho esto antes, inicia sesión con tu cuenta de Twitter. Crea una nueva aplicación llamada 'rvine' y una vez que lo hayas hecho, se te presentarán 2 claves de aplicación.
Crea un archivo de configuración en config/initializers/omniauth.rb. Una vez creado este archivo, ábrelo e introduce el siguiente código:
proveedor :twitter, "CONSUMER_KEY", "CONSUMER_SECRET"
fin
Esto debería significar que ya tenemos Omniauth configurado con nuestras claves de aplicación de Twitter, y casi listo para funcionar. Lo siguiente que tenemos que hacer es crear una ruta en nuestra aplicación Rails para gestionar el proceso de autenticación. Abrimos nuestro archivo config/routes.rb e introducimos lo siguiente:
Ahora le estamos diciendo a Rails que envíe nuestra llamada de retorno de Twitter Auth'd a nuestro controlador de sesiones.... ¿Qué controlador de sesiones? Tenemos que crearlo ahora.
Sigue adelante y crea el archivo app/controllers/sessions_controller.rb
def crear
usuario = Usuario.find_or_create_from_auth_hash(auth_hash)
sesión[:user_id] = usuario.id
flash[:éxito] = "¡Bienvenido al club!"
redirect_to dashboard_path
finprotegido
def auth_hash
solicitud.env[omniauth.auth]
fin
fin
Como se puede ver en este código, nuestro método 'Create' está llamando a la clase que definimos en nuestro User.rb para inicializar una sesión cuando un usuario hace clic para autenticarse desde el frontend, o crear el usuario si aún no existe. Una vez autenticado, redirigimos al usuario a su panel de control. (¡Que crearemos pronto!)
A continuación, vamos a actualizar nuestro application_controller.rb para incluir clases de ayuda para nuestra Autenticación - incluyendo un método de ayuda para definir un Current_User y un método de ayuda para asegurar que un Usuario está Registrado.
proteger_de_falsificacionesdef ¡Autenticar!
si signed_in?
devolver verdadero
si no
flash[:error] = "No está autorizado a acceder a esta página"
redirigir_a(ruta_raiz)
fin
fin
def usuario_actual
@usuario_actual ||= Usuario.buscar_por_id(sesión[:user_id])
fin
método_ayudante :usuario_actual
def signed_in?
Usuario_actual
fin
método_ayudante :signed_in?
fin
A continuación tenemos que crear el panel de control al que se redirigirá a nuestros usuarios una vez autorizados. Para ello usaremos un comando Rails Generate.
Ahora, vamos a abrir el archivo app/controllers/dashboards_controller.rb e introduce lo siguiente:
clase Cuadros de mandoController < Controlador de aplicación
def Mostrar
fin
fin
Vamos a abrir nuestra vista frontend del Dashboard, y editar eso. En mi caso, va a ser un archivo HAML. Independientemente de que elijas ERB o HAML, el archivo va a tener prácticamente el mismo aspecto. En app/views/paneles de control - basta con crear el archivo show.haml o show.erb.
.página–cabecera
– si signed_in?
%h1
Hola, #{current_user.name}
%p
%img{:src => usuario_actual.avatar, :alt => "Avatar"}
%p= enlace_a("Todas las vides", "/vines")
– si no
%h1
Hola, forastero
%p
= enlace_a("Inicia sesión con tu cuenta de twitter", "/auth/twitter")
%p
Ahora que ya tenemos nuestro panel de control, tenemos que configurar algunas rutas más, y luego podemos seguir adelante y probar las cosas. Abrir config/rutas.rb y añade lo siguiente:
Una vez hecho esto, guarda, ejecuta tu aplicación y autentifícate como usuario.
Perfecto. Ahora podemos ver que nuestra Autenticación funciona, y nuestros Usuarios tienen un Dashboard. Si abrimos nuestra consola de Couchbase, ¡también deberíamos ver que se ha creado un Usuario dentro de nuestro bucket de Rvine!
Ahora que tenemos nuestros usuarios y autenticación en su lugar, vamos a pasar a la parte principal de la aplicación: ¡Los videos de Vine! Para empezar, vamos a necesitar crear un modelo para Vines. Ahora, desafortunadamente, Couchbase-Model todavía no soporta el Generador de rails en esta acción. Así que tenemos que crear manualmente /app/models/vine.rb
Una vez hecho esto, vamos a rellenar lo siguiente:
requiere uri
requiere nokogiriclase Vid < Couchbase::Modelo
después_de_guardar :extraer_vídeo_url
pertenece_a :usuario
atributo :título
atributo :vine_url
atributo :video_url
#Voting API
atributo :puntuación, :por defecto => 1
valida_presencia_de :título, :vine_url
privado
def extraer_vídeo_url
doc = Nokogiri(abra(vine_url).leer)
auto.video_url = doc.css("fuente").primero["src"]
save_without_callbacks
fin
fin
Como podemos ver en el código anterior, estamos incluyendo open-uri, uri, y nokogiri. Esto se debe a que Vine no tiene una API pública, ¡pero necesitamos obtener esos vídeos de alguna manera! Así que, con la ayuda de estas librerías, hemos escrito un script descarado para rastrear la fuente de un vídeo de Vine y obtener el URI mp4 exacto cuando un usuario introduce la URL de Vine.
La clase extraer_vídeo_url mediante el método después_de_guardar. Del código podemos ver que Nokogiri abre la URL introducida por nuestro usuario al publicar un Vine. A continuación, busca la fuente de la página de Vine para encontrar la línea que declara la URI mp4 real de Vine.
Aparte de eso, podemos ver que cada Vine pertenece a un Usuario, tiene atributos para el Título, Vine URL (Introducido por el usuario) y Video URL (mp4 URI real). También tenemos un atributo Score. (El atributo más importante). Tenga en cuenta también que cada vídeo comienza con una puntuación de 1.
Ahora, vamos a generar un controlador y vistas para nuestro modelo Vine. Ejecutar:
Es posible que en este punto aparezca un error de conflicto diciendo que el modelo ya existe. No te preocupes, simplemente di 'N' para no sobrescribirlo. También puedes ver un error Couchbase not found. De nuevo, no te preocupes por esto, como he dicho antes Couchbase-Model no es compatible con el generador de modelos de Rails.
Si todo ha ido según lo previsto, ahora debería tener un vines_controller.rb y toda una carpeta de vistas para las vides con los archivos frontend HAML o ERB. Siga adelante y abra vines_controller.rb y asegúrese de que refleja la archivo aquí.
En nuestro archivo de controlador, es posible que haya notado un método llamado 'upvote'. Este es el mecanismo de votación para nuestros vídeos de Vine. Para terminar la implementación de este sistema de votación, y para dar realmente a los vídeos de Vine un lugar para vivir, abra el archivo app/views/vines/show.haml(o .erb)
Asegúrese de que relfects el archivo aquí…
Antes de que nuestro sistema de votación funcione completamente, tenemos que añadir lo siguiente a nuestro rutas.rb archivo:
miembro do
poner :upvote
fin
fin
Bien, ya podemos mostrar nuestros vídeos de Vine y el mecanismo de votación está en marcha. Lo siguiente que tenemos que hacer es configurar la página principal de la aplicación - La clasificación Nuestra tabla de clasificación, a pesar de ser la característica principal de la aplicación, es increíblemente sencilla. Abre el archivo app/views/vines/index.haml (o .erb) y asegúrese de que coincide con el código aquí.
Ahora bien, si se tratara de una aplicación Rails relacional normal y corriente, tendríamos que hacer lo siguiente debe en teoría tenemos una clasificación ya creada, con una lista de cada vídeo de Vine en nuestra base de datos. PERO este no es el caso aquí.
En Couchbase, tenemos que crear nuestra tabla de clasificación utilizando Vistas en Couchbase y utilizando la técnica Map/Reduce antes de conseguir una tabla de clasificación que funcione correctamente. Así que, ¡hagámoslo! Antes de continuar, si no has usado Couchbase Views antes de esto, te recomiendo que leas estos documentosEl objetivo de este artículo es ofrecerte una buena base sobre qué son las vistas de Couchbase, cómo las usamos y facilitarte su uso en esta aplicación Rails.
Para nuestra aplicación, necesitamos crear una vista en Couchbase, que muestre cada vídeo, con su puntuación y título. También necesitan ser ordenados, de forma descendente, por puntuación para que el vídeo Vine con la puntuación más alta esté naturalmente en la parte superior de la tabla de clasificación.
Si has usado Couchbase Views antes, puede que las hayas creado desde la propia consola de administración. Las Views se pueden crear desde dentro de la Admin UI, desde cualquiera de nuestros clientes SDK y mediante la REST API. En este caso, Couchbase-Model tiene una forma única y bastante brillante de permitirnos generar Views para nuestra aplicación. Echa un vistazo a estos documentos para ver cómo se puede hacer, y cómo estamos a punto de hacerlo.
En Terminal, simplemente ejecute:
Ahora, en su app/modelos deberías tener un nuevo subdirectorio llamado vine, con un subdirectorio llamado all. Este directorio contiene 2 archivos .js - nuestro map.js y reduce.js. Por ahora, todo lo que nos interesa es el archivo map.js. Adelante, ábrelo e introduce lo siguiente:
si (doc.tipo == "vid" && doc.título) {
emite(doc.puntuación, doc.título);
}
}
Como podemos ver en esta función Map, estamos envolviendo todo en una sentencia IF. Esta es una buena práctica dentro de Couchbase para comprobar los atributos antes de intentar emitir filas en nuestro índice. En este caso, nuestra sentencia IF está asegurando que sólo los documentos con el atributo tipo == "vid" y asegurándose de que la vid tiene un título. A continuación, la función emit crea una fila en nuestro índice utilizando el documento Puntuación como clave indexada. También estamos emitiendo el documento Título como valor de salida.
La razón por la que mostramos el Puntuación como clave indexada, es que podemos aprovechar la ordenación Unicode que Couchbase aplica automáticamente a este campo. En nuestro caso, necesitamos asegurarnos de que nuestra puntuación es descendente, para empujar el Vine con mayor puntuación a la parte superior de la tabla de clasificación. Esta función de mapa funcionará bien por sí sola, y si ejecutas la aplicación ahora, tendrás una lista de videos de Vine, ¡pero estarán en el orden equivocado!
Es hora de aplicar otra característica de Couchbase para pulir nuestro Leaderboard y asegurarnos de que funciona como debería. Es hora de Consultar nuestra vista para crear nuestro producto final. Una vez más, Couchbase-Model nos permite hacer esto directamente desde nuestro código Rails. Abre tu fichero de modelo vine.rb y añade la siguiente línea justo encima de la declaración 'private':
Este código no sólo es necesario para añadir parámetros de consulta a nuestra Vista, sino que debe añadirse a nuestro archivo Vine.rb con o sin parámetros de consulta para asegurarnos de que nuestra aplicación sabe qué Vista(s) tiene que utilizar en nuestra aplicación. En este caso, podemos ver, no sólo estamos definiendo qué vista debe utilizar nuestra aplicación, sino que también hemos añadido los parámetros de consulta:
De este modo, limitamos la salida de la vista a 10 resultados y nos aseguramos de que la función Puntuación está en orden descendente.
Ya está. Si rellenas tu base de datos con unos cuantos vídeos de Vine, deberías ver que tienes una aplicación Rate my Vine completamente funcional. A lo largo de este artículo hemos visto cómo podemos modelar datos con la gema Couchbase-Model de Couchbase Rails, hemos visto cómo podemos usar Views en Couchbase para crear aplicaciones interactivas, y hemos visto cómo podemos hacer Query en esas Views para obtener subconjuntos específicos de datos para usar en nuestra aplicación.
Me doy cuenta de que no todo lo que hay dentro de la aplicación está en este artículo (estilos, etc.), pero eso no tiene importancia. Espero haber cubierto los puntos principales (Couchbase-Model, Modelado de Documentos, Vistas y Consultas) lo suficientemente bien como para que sientas que puedes empezar tu propia aplicación Rails usando la gema Couchbase-Model.
Si es usted londinense, únase a nuestro Meetup de Couchbase en Londres ya que en las próximas semanas organizaremos eventos en los que se tratarán en detalle el modelado de documentos, Couchbase Mobile y muchos otros temas.
Si has leído hasta aquí, ¡sólo puedo felicitarte! Sé que ha sido un artículo LARGO. Si tienes alguna pregunta, como siempre, estaré encantada de responderte. Pégame en Twitter en @Rbin y envíame cualquier pregunta.
Robin Johnson
Defensor del Desarrollador, Europa.
gracias por compartirlo
Gracias. He usado esto con facebook omniauth y funciona a las mil maravillas :)
Hola Robin,
Estoy trabajando en una aplicación Rails y estoy teniendo problemas para almacenar imágenes como documentos blobs/binarios en couchbase. He intentado guardar los blobs en un atributo en Couchbase-model, pero parece que no lo maneja correctamente. Tengo la intención de profundizar en Couchbase-model para ver si hay una manera sencilla de almacenar y recuperar imágenes de couchbase, pero quería ver si sabías de algo. Gracias
[...] Blog Post of the Week #1 : Sample application - Ruby on Rails and Couchbase-Model for a Social... [...]