Es posible separar en motores una aplicación y reusar cada motor en diversas aplicaciones. Presentamos a continuación algunas ejemplos empleando Rails 4.2.0.beta4 sobre adJ 5.5 (puede ver una introducción al uso de Ruby on Rails sobre la plataforma adJ en {3}). 1. MOTORComo se explica en {1} pueden crearse motores aislados (o montables) o no aislados en Ruby on Rails 2. MOTOR NO AISLADO3. MOTOR AISLADOPara generar un motor aislado que use rspec para pruebas como se explica en {2}: rails plugin new s2g -T --mountable --full --dummy-path=spec/dummy Esto además del motor generará una aplicación de prueba en 3.1 Configuración inicial con rspec y uso automático de migraciones en aplicacionesComplete la configuración de rspec agregando al archivo gem "rspec-rails" gem "factory_girl_rails" Modifique module S2g class Engine < ::Rails::Engine isolate_namespace S2g config.generators do |g| g.test_framework :rspec g.fixture_replacement :factory_girl, :dir => 'spec/factories' end initializer :append_migrations do |app| unless app.root.to_s ``` root.to_s config.paths["db/migrate"].expanded.each do |expanded_path| app.config.paths["db/migrate"] << expanded_path end end end end end Prepare archivos de rspec rails generate rspec:install y modifique el archivo generado require File.expand_path("../../config/environment", __FILE__) por require File.expand_path("../dummy/config/environment", __FILE__) Además para que la aplicación de pruebe opere bien, agrege en require 's2g' 3.2 Generar un recursoAhora puede por ejemplo generar un recurso con: rails g scaffold actividad minutos:integer nombre:string que genera: | Contenido | Archivo(s) | | Migración | db/migrate/!20141117194927_create_s2g_actividads.rb | | Modelo | app/models/s2g/actividad.rb | | Prueba a modelo | spec/models/s2g/actividad_spec.r | | Modelos de ejemplo | spec/factories/s2g_actividads.rb | | Ruta a actividad | La agrega a config/routes.rb | | Controldor | app/controllers/s2g/actividads_controller.rb | | Vistas | app/views/s2g/actividads/index.html.erb, app/views/s2g/actividads/edit.html.erb, app/views/s2g/actividads/show.html.erb, app/views/s2g/actividads/new.html.erb app/views/s2g/actividads/_form.html.erb | | Pruebas a controlador | spec/controllers/s2g/actividads_controller_spec.rb | | Pruebas a vistas | spec/views/s2g/actividads/edit.html.erb_spec.rb, spec/views/s2g/actividads/index.html.erb_spec.rb, spec/views/s2g/actividads/new.html.erb_spec.rb, spec/views/s2g/actividads/show.html.erb_spec.rb, spec/routing/s2g/actividads_routing_spec.rb | | Pruebas a enrutador | spec/routing/s2g/actividads_routing_spec.rb | | Ayudas para vistas y controladores | app/helpers/s2g/actividads_helper.rb | | Prueba para ayudas | spec/helpers/s2g/actividads_helper_spec.rb | | | Recursos para vistas | app/assets/javascripts/s2g/actividads.js, app/assets/stylesheets/s2g/actividads.css, app/assets/stylesheets/scaffold.css | Notará que no usa inflección correcta en español –ni aún si la agrega en !ActiveSupport::Inflector.inflections do |inflect| inflect.irregular 'actividad', 'actividades' end Y renombre manualmente archivos y cambien nombres erradamente generados, por ejemplo con: for i in `find . -name "*ctividads*"`; do echo $i; n=`echo $i | sed "s/ctividads/ctividades/g"`; echo $n; mv $i $n; done for i in `find . -exec grep -l "ctividads" {} ';'`; do echo $i; cp $i /tmp/t; sed -e "s/ctividads/ctividades/g" /tmp/t > $i; done 3.3 Aplicación de pruebaPara ver el recurso operando en la aplicación de prueba, pase al directorio de la misma e inicie la base: cd spec/dummy rake db:setup rake db:migrate Note que si no configuró uso automático de migraciones del motor como se explicó en la sección 3.1, tendrá que ejecutar: Tras esto puede iniciar el servidor de desarrollo ( Si prefiere que la aplicación de prueba no emplee mount S2g::Engine => "/s2g" por mount S2g::Engine => "/" 3.4 Pruebas con rspecPrepara base para pruebas con: cd spec/dummy RAILS_ENV=test rake db:setup RAILS_ENV=test rake db:migrate Debería bastar que después desde el directorio del motor ejecute rspec pues como se explica en https://www.relishapp.com/rspec/rspec-rails/docs/routing-specs/engine-routes rspec ahora tiene soporte para probar motores. Sin embargo en el momento de este escrito al probar con Rails 4.2.0.beta3 y rspec 3.1.7 vemos 12 fallas porque los generadores no dejan todo perfecto, deben realizarse los siguientes cambios.
routes { S2g::Engine.routes }
3.5 Una aplicación que usa el motorPuede iniciarla con: rails new s2 -T Añada una referencia al motor en Gemfile: gem 's2g', path: '../s2g' Configure rspec añadiendo a Gemfile en la sección gem 'rspec-rails' Instale gemas necesarias: bundle install Configure rutas en Rails.application.routes.draw do mount S2g::Engine => "/", as: 's2g' end 3.6. Decoradores para modificar clases de un motorComo se explica en {1}, otros detalles: * Los decoradores se cargan como parte de la inicialización * Con la instrucción de {1} se cargan sólo los decoradores de la aplicación, no de los motores. Los decoradores definidos en motores se deben cargar desde los decoradores de la aplicación. 4. PASANDO DE UN MOTOR AISLADO A UNO NO AISLADOSe presentarán ejemplos tomados de sivel2_gen: En isolate_namespace !Sivel2Gen 4.1 ModelosCrear una migración que renombre tablas class !RenombraAislasjr < !ActiveRecord::Migration def change rename_table :pais, :sivel2_gen_pais ... end end Mover modelos de Agregar módulo a modelos del motor. Por ejemplo pasar de # encoding: UTF-8 class Pais < !ActiveRecord::Base include Basica end a # encoding: UTF-8 module !Sivel2Gen class Pais < !ActiveRecord::Base include Basica end end El siguiente script para awk ayuda /.*/ { if (lin ``` 2) { print "module !Sivel2Gen"; } if (lin >= 2) { print " " $0; } else { print $0; } lin++; } BEGIN { lin = 1; } END { if (lin > 2) { print "end"; } } Poner la clase explicita en cada relacion has_many :aslegal_respuesta, foreign_key: "id_aslegal", validate: true, dependent: :destroy has_many :respuesta, :through => :aslegal_respuesta a has_many :aslegal_respuesta, class_name: '!Sivel2Sjr::!AslegalRespuesta', foreign_key: "id_aslegal", validate: true, dependent: :destroy has_many :respuesta, :through => :aslegal_respuesta, class_name: '!Sivel2Sjr::Respuesta' 4.2 ControladoresDebe hacerse un cambio análogo al de modelos pasandolos de
app/controllers/ a app/controllers/sivel2_gen y agregando en cada clase
Es posible que en algunos casos deba referenciar modelos usando el espacio de nombre, e.g Si utiliza !CanCan en algunos contralodores puede requerir indicar la clase explicitamente para cargar y autorizar recursos automáticamente. Por ejemplo en el controlador load_and_authorize_resource por load_and_authorize_resource class: !Sivel2Gen::Actividadarea 4.3 VistasIgualmente deben moverse de En las vistas las referencias a clases deben incluir el espacio de nombres, por ejemplo en lugar de: <%= f.association :pais, collection: Pais.habilitados, label_method: :nombre, value_method: :id %> usar <%= f.association :pais, collection: !Sivel2Gen::Pais.habilitados, label_method: :nombre, value_method: :id %> Los nombres de clases en los archivos de localización con traducciones deben renombrarse, pasar en actividadarea: Actividadarea: Área de Actividad Actividadareas: Áreas de Actividades a "sivel2_gen/actividadarea": Actividadarea: Área de Actividad Actividadareas: Áreas de Actividades 4.4 Pruebas con rspecDeben pasarse de spec/{models,controllers,routing,views,request}/ a spec/sivel2_gen/{models,controllers,routing,views,ruquests} Deben renombrarse las "fabricas" de Factory Girls, del directorio mv caso.rb sivel2_gen_caso.rb En cada una de estas "fabricas" debe cambiarse el nombre y añadir la clase explicitamente, por ejemplo pasando de factory :caso do a factory :sivel2_gen_caso, class: "Sivel2Gen::Caso" do Aplican los mismos comentarios de la sección 3.5 y además. * En las pruebas a modelos cambiar nombre en uso de FactoryGirl, como se acaba de describir 5. MOTORES QUE USAN MOTORES
6. REFERENCIAS
|