Sign inSign up

yavende/web

By yavende

•Updated over 9 years ago

Old rails site for YaVende.com

Image
0

8.0K

yavende/web repository overview

⁠YaCompara

Applicación Rails que sirve el sitio www.yavende.com⁠.

⁠Documentación

El proyecto tiene cierto nivel de doc coverage provisto por YARD. Examinar doc/index.html.

⁠Stack Tecnológico

  • Rails 4.x.x
  • Ruby 2.x.x
  • AngularJS > 1.5
  • Bower con [bower-rails][1]
  • Administrate

⁠Alcanze del proyecto

El scope del proyecto abarca proveer un front en donde usuarios anónimos pueden crear avisos de venta de autos, buscarlos, y efectuar algunas operaciónes relacionadas con el aviso, como denunciar que el aviso fue publicado por una agencía, o recuperar el link de edición.

No hay login, por lo que la edición de un aviso se hace mediante un link que contiene un token en la url que es provisto al dueño del aviso por mail.

Para la parte del administrador, es posible ver y crear y editar avisos, administrar las marcas, modelos y versiones de auto, importar modelos de auto por CSV, CMS, y administrar usuarios.

⁠Estructura general

La app consiste de una single page hecha en angular, una API Rest pensada para ser consumida desde el front y un backend hecho con Administrate.

# config/routes.rb
  # ...

  namespace :admin do
    # ...
  end

  namespace :api do
    # ...
  end

  controller :single_page do
    get "/templates/(*path)", action: :render_template
    root action: :index
    get "*path", action: :index
  end

  # ...

Gran parte de los assets para el front estan instalados con [bower-rails][1], una gema que permite appendear los packetes instalados con bower directamente en los load_paths de sprockets.

⁠Arquitectura

⁠Avisos

CarListing es el modelo que represanta los avisos. Importante: debido a un requerimiento de negocio, cuando los avisos son updateados desde del front, generan una copia de si mismos con el objecto de persistir al mismo tiempo, el aviso no aprobado con los nuevos cambios, y el aviso aprobado que se tiene que mostrar en los listados de búsqueda.

Esta funcionalidad esta encapsulada en los módulos Approvable y Versionable. Example usage:

class CarListing < ActiveRecord::Base
  include Approvable

  # ...

  self.options_for_clone = {
    include: [
      :inspector, :car, :seller,
      :publication_manager, :sale_manager,
      :manager, :auditor,
      car: %i[images location],
      seller: %i[location]
    ],
    exclude: :validate_terms_of_service
  }

  # ...
end

CarListing.first.update(price: 2, create_clone: true)

donde options_for_clone se pasa directamente a [deep_clone][2].

Por otro lado, CarListing tiene subtipos como CarListing::Classic con el objecto de encapsular validaciones distintas y otro comportamiento especial.

⁠Marcas, modelos y versiones de auto

Los avisos tienen un Car, y el auto tiene una Car::Version, que pertenece a un Car::Model, que a su vez pertenece a un Car::Brand.

Este arbol de marcas, modelos y versiones es importable por CSV. El código que se encarga de ello está en Car::Version::Import. Esta clase es un modelo y se encarga de persistir y parsear el archivo CSV, lo cual se debería hacer en background. Está preparado para aceptar CSV en el siguiente formato:

nombre_de_la_marca, nombre_del_modelo, nombre_de_la_version, 1990, 1991, 1992, 1993, 1994, [...]
FORD              , FOCUS,           , 1.6 GT              , 1   ,     ,     , 1   ,

Lo que se traduce en la creación de una marca con mobre FORD, si no existe, un modelo FOCUS, una versión 1.6 GT con años [1990, 1993].

⁠Búsquedas

Las búsquedas se implementaron con un poco de ayuda de [searchlight][3]. Todas las búequedas heredan de Abstract Search, una clase que encapsula un poco el boiler plate que se repite en todas las búequedas, y provee un pequeño DSL opcional que permite definir creiteriods de búsqueda en una sola línea. Más información en YARD.

⁠Estructura del los archivos de AngularJS

Todo el código de angular esta en app/assets/javascripts/angular/**/*. Presenta la siguiente estructura:

angular
|--app          # donde se declara el modulo `yaComparaFront`
|--config       # bloques `angluar.module("yaComparaFront").config` para configuración de plugins
|--initializers # código que se corre antes de que angular empieze a dibujar la app
|--directives
|--factories
|--services

Los clientes de javascript que se comunican con la API usan [angularjs-rails-resource][4] y necesitan de un interceptor de request RestErrorsInterceptor que toma los errores que viene de la API y los injectan en la instancia y sus associaciones anidadas. Este comportamiento depende profundamente de lo implementado en su contraparte en ruby RestfulController::ErrorsSerializer.

⁠Gotchas

  • Importante que en produción uglifier este configurando con:

⁠Compress JavaScripts and CSS.

config.assets.js_compressor = Uglifier.new(mangle: false)


.. para no romper el dependency injection de angular cuando uglifier manglea los nombres de los argumento
de las funciones. La alternativa es usar algo como [ngannotate-rails][5], o usar [otras formas de dependency injection
mas feas][6].

[1]: https://github.com/rharriso/bower-rails
[2]: https://github.com/moiristo/deep_cloneable
[3]: https://github.com/nathanl/searchlight
[4]: https://github.com/FineLinePrototyping/angularjs-rails-resource
[5]: https://github.com/kikonen/ngannotate-rails
[6]: https://docs.angularjs.org/guide/di

Tag summary

Content type

Image

Digest

Size

379.2 MB

Last updated

over 9 years ago

docker pull yavende/web