1 Actualización a Rails 3.2
Si está actualizando una aplicación existente, es una buena idea tener una buena cobertura de pruebas antes de comenzar. También debe actualizar primero a Rails 3.1 en caso de que no lo haya hecho y asegurarse de que su aplicación siga funcionando como se espera antes de intentar una actualización a Rails 3.2. Luego, tenga en cuenta los siguientes cambios:
1.1 Rails 3.2 requiere al menos Ruby 1.8.7
Rails 3.2 requiere Ruby 1.8.7 o superior. El soporte para todas las versiones anteriores de Ruby se ha eliminado oficialmente y debe actualizar lo antes posible. Rails 3.2 también es compatible con Ruby 1.9.2.
CONSEJO: Tenga en cuenta que Ruby 1.8.7 p248 y p249 tienen errores de serialización que hacen que Rails se bloquee. Ruby Enterprise Edition los ha corregido desde el lanzamiento de 1.8.7-2010.02. En cuanto a la versión 1.9, Ruby 1.9.1 no se puede usar porque se bloquea por completo, por lo que si desea usar 1.9.x, pase a 1.9.2 o 1.9.3 para un funcionamiento sin problemas.
1.2 Qué actualizar en sus aplicaciones
Actualice su
Gemfile
para depender derails = 3.2.0
sass-rails ~> 3.2.3
coffee-rails ~> 3.2.1
uglifier >= 1.0.3
Rails 3.2 deprecia
vendor/plugins
y Rails 4.0 los eliminará por completo. Puede comenzar a reemplazar estos complementos extrayéndolos como gemas y agregándolos en suGemfile
. Si elige no convertirlos en gemas, puede moverlos a, por ejemplo,lib/my_plugin/*
y agregar un inicializador adecuado enconfig/initializers/my_plugin.rb
.Hay algunos cambios de configuración nuevos que debe agregar en
config/environments/development.rb
:# Levanta una excepción en la protección de asignación masiva para modelos de Active Record config.active_record.mass_assignment_sanitizer = :strict # Registra el plan de consulta para consultas que tardan más de esto (funciona # con SQLite, MySQL y PostgreSQL) config.active_record.auto_explain_threshold_in_seconds = 0.5
La configuración
mass_assignment_sanitizer
también debe agregarse enconfig/environments/test.rb
:# Levanta una excepción en la protección de asignación masiva para modelos de Active Record config.active_record.mass_assignment_sanitizer = :strict
1.3 Qué actualizar en sus motores
Reemplace el código debajo del comentario en script/rails
con el siguiente contenido:
ENGINE_ROOT = File.expand_path('../..', __FILE__)
ENGINE_PATH = File.expand_path('../../lib/your_engine_name/engine', __FILE__)
require "rails/all"
require "rails/engine/commands"
2 Creando una aplicación Rails 3.2
# Debe tener instalada la gema 'rails'
$ rails new myapp
$ cd myapp
2.1 Empaquetando gemas
Rails ahora utiliza un Gemfile
en la raíz de la aplicación para determinar las gemas que necesita para que su aplicación se inicie. Este Gemfile
es procesado por la gema Bundler, que luego instala todas las dependencias. Incluso puede instalar todas las dependencias localmente en su aplicación para que no dependa de las gemas del sistema.
Más información: Página principal de Bundler
2.2 Viviendo al límite
Bundler
y Gemfile
facilitan congelar su aplicación Rails con el nuevo comando bundle
dedicado. Si desea empaquetar directamente desde el repositorio Git, puede pasar la bandera --edge
:
$ rails new myapp --edge
Si tiene una copia local del repositorio de Rails y desea generar una aplicación utilizando eso, puede pasar la bandera --dev
:
$ ruby /ruta/a/rails/railties/bin/rails new myapp --dev
3 Características principales
3.1 Modo de desarrollo y enrutamiento más rápido
Rails 3.2 viene con un modo de desarrollo notablemente más rápido. Inspirado en Active Reload, Rails recarga las clases solo cuando los archivos realmente cambian. Las mejoras de rendimiento son dramáticas en una aplicación más grande. El reconocimiento de rutas también se volvió mucho más rápido gracias al nuevo motor Journey.
3.2 Explicaciones automáticas de consultas
Rails 3.2 viene con una función interesante que explica las consultas generadas por Arel al definir un método explain
en ActiveRecord::Relation
. Por ejemplo, puede ejecutar algo como puts Person.active.limit(5).explain
y se explicará la consulta que Arel produce. Esto permite verificar los índices adecuados y realizar optimizaciones adicionales.
Las consultas que tardan más de medio segundo en ejecutarse se explican automáticamente en el modo de desarrollo. Por supuesto, este umbral se puede cambiar.
3.3 Registro etiquetado
Cuando se ejecuta una aplicación multiusuario y multi cuenta, es de gran ayuda poder filtrar el registro por quién hizo qué. TaggedLogging en Active Support ayuda a hacer exactamente eso al marcar las líneas de registro con subdominios, identificadores de solicitud y cualquier otra cosa que ayude a depurar dichas aplicaciones.
4 Documentación
A partir de Rails 3.2, las guías de Rails están disponibles para Kindle y las aplicaciones gratuitas de lectura de Kindle para iPad, iPhone, Mac, Android, etc.
5 Railties
Acelera el desarrollo al volver a cargar solo las clases si los archivos de dependencias han cambiado. Esto se puede desactivar configurando
config.reload_classes_only_on_change
en falso.Las nuevas aplicaciones obtienen una bandera
config.active_record.auto_explain_threshold_in_seconds
en los archivos de configuración de entornos. Con un valor de0.5
endevelopment.rb
y comentado enproduction.rb
. No se menciona entest.rb
.Se agregó
config.exceptions_app
para establecer la aplicación de excepciones invocada por el middlewareShowException
cuando ocurre una excepción. El valor predeterminado esActionDispatch::PublicExceptions.new(Rails.public_path)
.Se agregó un middleware
DebugExceptions
que contiene características extraídas del middlewareShowExceptions
.Muestra las rutas de los motores montados en
rake routes
.Permite cambiar el orden de carga de los railties con
config.railties_order
de la siguiente manera:config.railties_order = [Blog::Engine, :main_app, :all]
Scaffold devuelve 204 No Content para solicitudes de API sin contenido. Esto hace que scaffold funcione con jQuery de inmediato.
Actualiza el middleware
Rails::Rack::Logger
para aplicar cualquier etiqueta establecida enconfig.log_tags
aActiveSupport::TaggedLogging
. Esto facilita etiquetar las líneas de registro con información de depuración como el subdominio y el identificador de solicitud, ambos muy útiles en la depuración de aplicaciones de producción multiusuario.Las opciones predeterminadas para
rails new
se pueden establecer en~/.railsrc
. Puede especificar argumentos adicionales de línea de comandos que se utilizarán cada vez que se ejecuterails new
en el archivo de configuración.railsrc
en su directorio de inicio.Agrega un alias
d
paradestroy
. Esto también funciona para los motores.Los atributos en los generadores de scaffold y modelo tienen como valor predeterminado string. Esto permite lo siguiente:
bin/rails g scaffold Post title body:text author
Los generadores de scaffold/modelo/migración ahora aceptan modificadores "index" y "uniq". Por ejemplo,
bin/rails g scaffold Post title:string:index author:uniq price:decimal{7,2}
creará índices para
title
yauthor
, siendo este último un índice único. Algunos tipos como decimal aceptan opciones personalizadas. En el ejemplo,price
será una columna decimal con precisión y escala establecidas en 7 y 2 respectivamente.La gema Turn se ha eliminado del archivo
Gemfile
predeterminado.Se eliminó el antiguo generador de complementos
rails generate plugin
a favor del comandorails plugin new
.Se eliminó la antigua API
config.paths.app.controller
a favor deconfig.paths["app/controller"]
.
5.1 Deprecaciones
Rails::Plugin
está obsoleto y se eliminará en Rails 4.0. En lugar de agregar complementos avendor/plugins
, use gemas o bundler con dependencias de ruta o git.
6 Action Mailer
Se actualizó la versión de
mail
a 2.4.0.Se eliminó la antigua API de Action Mailer que estaba obsoleta desde Rails 3.0.
7 Action Pack
7.1 Action Controller
Hace que
ActiveSupport::Benchmarkable
sea un módulo predeterminado paraActionController::Base
, por lo que el método#benchmark
vuelve a estar disponible en el contexto del controlador como solía ser.Se agregó la opción
:gzip
acaches_page
. La opción predeterminada se puede configurar globalmente utilizandopage_cache_compression
.Ahora Rails utilizará su diseño predeterminado (como "layouts/application") cuando especifique un diseño con la condición
:only
y:except
, y esas condiciones no se cumplan.class CarsController layout 'single_car', :only => :show end
Rails utilizará
layouts/single_car
cuando se realice una solicitud en la acción:show
, y utilizarálayouts/application
(olayouts/cars
, si existe) cuando se realice una solicitud en cualquier otra acción.form_for
se cambió para usar#{action}_#{as}
como la clase y el id de CSS si se proporciona la opción:as
. Las versiones anteriores usaban#{as}_#{action}
.ActionController::ParamsWrapper
en los modelos de Active Record ahora solo envuelve los atributosattr_accessible
si se han establecido. Si no, solo se envolverán los atributos devueltos por el método de claseattribute_names
. Esto soluciona el envoltorio de atributos anidados agregándolos aattr_accessible
.Registra "Filter chain halted as CALLBACKNAME rendered or redirected" cada vez que un callback anterior se detiene.
Se refactorizó
ActionDispatch::ShowExceptions
. El controlador es responsable de elegir si mostrar excepciones. Es posible anularshow_detailed_exceptions?
en los controladores para especificar qué solicitudes deben proporcionar información de depuración en caso de errores.Los respondedores ahora devuelven 204 No Content para solicitudes de API sin cuerpo de respuesta (como en el nuevo scaffold).
Se refactorizó
ActionController::TestCase
cookies. Asignar cookies para casos de prueba ahora debe usarcookies[]
.ruby cookies[:email] = '[email protected]' get :index assert_equal '[email protected]', cookies[:email]
Para borrar las cookies, usa clear
.
cookies.clear
get :index
assert_nil cookies[:email]
Ahora ya no escribimos HTTP_COOKIE y el jar de cookies es persistente entre las solicitudes, por lo que si necesitas manipular el entorno para tu prueba, debes hacerlo antes de que se cree el jar de cookies.
send_file
ahora adivina el tipo MIME a partir de la extensión del archivo si no se proporciona:type
.Se agregaron entradas de tipo MIME para PDF, ZIP y otros formatos.
Se permite que
fresh_when/stale?
tome un registro en lugar de un hash de opciones.Se cambió el nivel de registro de advertencia por falta de token CSRF de
:debug
a:warn
.Los activos deben usar el protocolo de solicitud de forma predeterminada o, si no hay solicitud disponible, usar el valor predeterminado relativo.
7.1.1 Deprecaciones
- Se deprecó la búsqueda implícita de diseño en controladores cuyo padre tenía un diseño explícito establecido:
class ApplicationController
layout "application"
end
class PostsController < ApplicationController
end
En el ejemplo anterior, PostsController
ya no buscará automáticamente un diseño de posts. Si necesitas esta funcionalidad, puedes eliminar layout "application"
de ApplicationController
o establecerlo explícitamente en nil
en PostsController
.
Se deprecó
ActionController::UnknownAction
a favor deAbstractController::ActionNotFound
.Se deprecó
ActionController::DoubleRenderError
a favor deAbstractController::DoubleRenderError
.Se deprecó
method_missing
a favor deaction_missing
para acciones faltantes.Se deprecó
ActionController#rescue_action
,ActionController#initialize_template_class
yActionController#assign_shortcuts
.
7.2 Action Dispatch
Se agregó
config.action_dispatch.default_charset
para configurar el conjunto de caracteres predeterminado paraActionDispatch::Response
.Se agregó el middleware
ActionDispatch::RequestId
que hace que un encabezado X-Request-Id único esté disponible en la respuesta y habilita el métodoActionDispatch::Request#uuid
. Esto facilita el seguimiento de solicitudes de principio a fin en la pila y permite identificar solicitudes individuales en registros mixtos como Syslog.El middleware
ShowExceptions
ahora acepta una aplicación de excepciones que se encarga de renderizar una excepción cuando la aplicación falla. La aplicación se invoca con una copia de la excepción enenv["action_dispatch.exception"]
y conPATH_INFO
reescrito al código de estado.Se permite configurar las respuestas de rescate a través de un railtie como en
config.action_dispatch.rescue_responses
.
7.2.1 Deprecaciones
- Se deprecó la capacidad de establecer un conjunto de caracteres predeterminado a nivel de controlador, en su lugar, usa el nuevo
config.action_dispatch.default_charset
.
7.3 Action View
- Se agregó soporte
button_tag
aActionView::Helpers::FormBuilder
. Este soporte imita el comportamiento predeterminado desubmit_tag
.
<%= form_for @post do |f| %>
<%= f.button %>
<% end %>
Los ayudantes de fecha aceptan una nueva opción
:use_two_digit_numbers => true
, que renderiza cuadros de selección para meses y días con un cero inicial sin cambiar los valores respectivos. Por ejemplo, esto es útil para mostrar fechas en estilo ISO 8601 como '2011-08-01'.Puedes proporcionar un espacio de nombres para tu formulario para asegurar la unicidad de los atributos id en los elementos del formulario. El atributo de espacio de nombres se prefijará con un guión bajo en el id HTML generado.
<%= form_for(@offer, :namespace => 'namespace') do |f| %>
<%= f.label :version, 'Version' %>:
<%= f.text_field :version %>
<% end %>
Limita el número de opciones para
select_year
a 1000. Pasa la opción:max_years_allowed
para establecer tu propio límite.content_tag_for
ydiv_for
ahora pueden tomar una colección de registros. También cederá el registro como primer argumento si estableces un argumento receptor en tu bloque. Entonces, en lugar de hacer esto:
@items.each do |item|
content_tag_for(:li, item) do
Title: <%= item.title %>
end
end
Puedes hacer esto:
content_tag_for(:li, @items) do |item|
Title: <%= item.title %>
end
- Se agregó el método de ayuda
font_path
que calcula la ruta a un activo de fuente enpublic/fonts
.
7.3.1 Deprecaciones
- Pasar formatos o controladores a
render :template
y similares comorender :template => "foo.html.erb"
está deprecado. En su lugar, puedes proporcionar:handlers
y:formats
directamente como opciones:render :template => "foo", :formats => [:html, :js], :handlers => :erb
.
7.4 Sprockets
- Se agrega la opción de configuración
config.assets.logger
para controlar el registro de Sprockets. Establécelo enfalse
para desactivar el registro y ennil
para usarRails.logger
de forma predeterminada.
8 Active Record
Las columnas booleanas con valores 'on' y 'ON' se convierten en verdadero.
Cuando el método
timestamps
crea las columnascreated_at
yupdated_at
, las hace no nulas de forma predeterminada.Se implementó
ActiveRecord::Relation#explain
.Se implementó
ActiveRecord::Base.silence_auto_explain
, que permite al usuario desactivar selectivamente los EXPLAIN automáticos dentro de un bloque.Se implementó el registro automático de EXPLAIN para consultas lentas. Un nuevo parámetro de configuración
config.active_record.auto_explain_threshold_in_seconds
determina qué se considera una consulta lenta. Establecerlo ennil
desactiva esta función. Los valores predeterminados son 0.5 en modo de desarrollo ynil
en modos de prueba y producción. Rails 3.2 admite esta función en SQLite, MySQL (adaptador mysql2) y PostgreSQL.Se agregó
ActiveRecord::Base.store
para declarar almacenes de clave/valor simples de una sola columna.class User < ActiveRecord::Base store :settings, accessors: [ :color, :homepage ] end u = User.new(color: 'black', homepage: '37signals.com') u.color # Atributo almacenado por el accessor u.settings[:country] = 'Denmark' # Cualquier atributo, incluso si no se especifica con un accessor
Se agregó la capacidad de ejecutar migraciones solo para un alcance dado, lo que permite ejecutar migraciones solo desde un motor (por ejemplo, para revertir cambios de un motor que se deben eliminar).
rake db:migrate SCOPE=blog
Las migraciones copiadas de los motores ahora están agrupadas con el nombre del motor, por ejemplo
01_create_posts.blog.rb
.Se implementó el método
ActiveRecord::Relation#pluck
que devuelve una matriz de valores de columna directamente de la tabla subyacente. Esto también funciona con atributos serializados.Client.where(:active => true).pluck(:id) # SELECT id from clients where active = 1
Los métodos de asociación generados se crean dentro de un módulo separado para permitir la anulación y composición. Para una clase llamada MyModel, el módulo se llama
MyModel::GeneratedFeatureMethods
. Se incluye en la clase del modelo inmediatamente después del módulogenerated_attributes_methods
definido en Active Model, por lo que los métodos de asociación anulan los métodos de atributo con el mismo nombre.Se agregó
ActiveRecord::Relation#uniq
para generar consultas únicas.Client.select('DISTINCT name')
..se puede escribir como:
Client.select(:name).uniq
Esto también te permite revertir la unicidad en una relación:
Client.select(:name).uniq.uniq(false)
Se admite el orden de clasificación de índices en los adaptadores SQLite, MySQL y PostgreSQL.
Se permite que la opción
:class_name
para las asociaciones tome un símbolo además de una cadena. Esto es para evitar confusiones a los principiantes y ser coherente con el hecho de que otras opciones como:foreign_key
ya permiten un símbolo o una cadena.has_many :clients, :class_name => :Client # Nota que el símbolo debe estar en mayúscula
En el modo de desarrollo,
db:drop
también elimina la base de datos de prueba para ser simétrico condb:create
.La validación de unicidad sin distinción entre mayúsculas y minúsculas evita llamar a LOWER en MySQL cuando la columna ya utiliza una intercalación sin distinción entre mayúsculas y minúsculas.
Los fixtures transaccionales enlistan todas las conexiones de base de datos activas. Puedes probar modelos en diferentes conexiones sin deshabilitar los fixtures transaccionales.
Se agregaron los métodos
first_or_create
,first_or_create!
,first_or_initialize
a Active Record. Este es un enfoque mejor que los antiguos métodos dinámicosfind_or_create_by
porque es más claro qué argumentos se utilizan para encontrar el registro y cuáles se utilizan para crearlo.User.where(:first_name => "Scarlett").first_or_create!(:last_name => "Johansson")
Se agregó un método
with_lock
a los objetos de Active Record, que inicia una transacción, bloquea el objeto (de manera pesimista) y cede el control al bloque. El método toma un parámetro (opcional) y lo pasa alock!
.Esto permite escribir lo siguiente:
class Order < ActiveRecord::Base def cancel! transaction do lock! # ... lógica de cancelación end end end
como:
class Order < ActiveRecord::Base def cancel! with_lock do # ... lógica de cancelación end end end
8.1 Deprecaciones
Se deprecó el cierre automático de conexiones en hilos. Por ejemplo, el siguiente código está deprecado:
Thread.new { Post.find(1) }.join
Debe cambiarse para cerrar la conexión de la base de datos al final del hilo:
Thread.new { Post.find(1) Post.connection.close }.join
Solo las personas que generan hilos en su código de aplicación deben preocuparse por este cambio.
Los métodos
set_table_name
,set_inheritance_column
,set_sequence_name
,set_primary_key
,set_locking_column
están deprecados. En su lugar, utiliza un método de asignación. Por ejemplo, en lugar deset_table_name
, utilizaself.table_name=
.class Project < ActiveRecord::Base self.table_name = "project" end
O define tu propio método
self.table_name
:class Post < ActiveRecord::Base def self.table_name "special_" + super end end Post.table_name # => "special_posts"
9 Active Model
Se agregó
ActiveModel::Errors#added?
para verificar si se ha agregado un error específico.Se agregó la capacidad de definir validaciones estrictas con
strict => true
que siempre genera una excepción cuando falla.Se proporciona
mass_assignment_sanitizer
como una API fácil para reemplazar el comportamiento del sanitizador. También se admite el comportamiento del sanitizador:logger
(predeterminado) y:strict
.
9.1 Deprecaciones
Se deprecó
define_attr_method
enActiveModel::AttributeMethods
porque esto solo existía para admitir métodos comoset_table_name
en Active Record, que a su vez están siendo deprecados.Se deprecó
Model.model_name.partial_path
a favor demodel.to_partial_path
.
10 Active Resource
- Respuestas de redireccionamiento: las respuestas 303 See Other y 307 Temporary Redirect ahora se comportan como 301 Moved Permanently y 302 Found.
11 Active Support
Se agregó
ActiveSupport:TaggedLogging
que puede envolver cualquier claseLogger
estándar para proporcionar capacidades de etiquetado.Logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT)) Logger.tagged("BCX") { Logger.info "Stuff" } # Registra "[BCX] Stuff" Logger.tagged("BCX", "Jason") { Logger.info "Stuff" } # Registra "[BCX] [Jason] Stuff" Logger.tagged("BCX") { Logger.tagged("Jason") { Logger.info "Stuff" } } # Registra "[BCX] [Jason] Stuff"
El método
beginning_of_week
enDate
,Time
yDateTime
acepta un argumento opcional que representa el día en el que se asume que comienza la semana.ActiveSupport::Notifications.subscribed
proporciona suscripciones a eventos mientras se ejecuta un bloque.Se definieron nuevos métodos
Module#qualified_const_defined?
,Module#qualified_const_get
yModule#qualified_const_set
que son análogos a los métodos correspondientes en la API estándar, pero aceptan nombres de constantes calificadas.Se agregó
#deconstantize
que complementa a#demodulize
en inflexiones. Esto elimina el segmento más a la derecha en un nombre de constante calificada.Se agregó
safe_constantize
que convierte una cadena en una constante pero devuelvenil
en lugar de generar una excepción si la constante (o parte de ella) no existe.ActiveSupport::OrderedHash
ahora está marcado como extraíble cuando se utilizaArray#extract_options!
.Se agregó
Array#prepend
como un alias deArray#unshift
yArray#append
como un alias deArray#<<
.La definición de una cadena en blanco para Ruby 1.9 se ha ampliado para incluir espacios en blanco Unicode. Además, en Ruby 1.8, se considera que el espacio ideográfico U`3000 es un espacio en blanco.
El inflector comprende acrónimos.
Se agregaron
Time#all_day
,Time#all_week
,Time#all_quarter
yTime#all_year
como una forma de generar rangos.Event.where(:created_at => Time.now.all_week) Event.where(:created_at => Time.now.all_day)
Se agregó
instance_accessor: false
como una opción paraClass#cattr_accessor
y amigos.ActiveSupport::OrderedHash
ahora tiene un comportamiento diferente para#each
y#each_pair
cuando se le proporciona un bloque que acepta sus parámetros con un asterisco.Se agregó
ActiveSupport::Cache::NullStore
para su uso en desarrollo y pruebas.Se eliminó
ActiveSupport::SecureRandom
a favor deSecureRandom
de la biblioteca estándar.
11.1 Deprecaciones
ActiveSupport::Base64
está en desuso a favor de::Base64
.Se deprecó
ActiveSupport::Memoizable
a favor del patrón de memorización de Ruby.Module#synchronize
está en desuso sin reemplazo. Por favor, use el monitor de la biblioteca estándar de Ruby.Se deprecó
ActiveSupport::MessageEncryptor#encrypt
yActiveSupport::MessageEncryptor#decrypt
.ActiveSupport::BufferedLogger#silence
está en desuso. Si desea silenciar los registros para un determinado bloque, cambie el nivel de registro para ese bloque.ActiveSupport::BufferedLogger#open_log
está en desuso. Este método no debería haber sido público en primer lugar.Está en desuso el comportamiento de
ActiveSupport::BufferedLogger
de crear automáticamente el directorio para el archivo de registro. Asegúrese de crear el directorio para su archivo de registro antes de instanciarlo.ActiveSupport::BufferedLogger#auto_flushing
está en desuso. Establezca el nivel de sincronización en el controlador de archivos subyacente de la siguiente manera. O ajuste su sistema de archivos. Ahora es la caché del sistema de archivos la que controla el vaciado.f = File.open('foo.log', 'w') f.sync = true ActiveSupport::BufferedLogger.new f
ActiveSupport::BufferedLogger#flush
está en desuso. Establezca la sincronización en su controlador de archivos o ajuste su sistema de archivos.
12 Créditos
Consulte la lista completa de colaboradores de Rails para conocer a las muchas personas que pasaron muchas horas haciendo de Rails el marco estable y robusto que es. Felicitaciones a todos ellos.
Las Notas de la versión de Rails 3.2 fueron compiladas por Vijay Dev.
Comentarios
Se te anima a ayudar a mejorar la calidad de esta guía.
Por favor, contribuye si encuentras algún error tipográfico o factual. Para empezar, puedes leer nuestra contribución a la documentación sección.
También puedes encontrar contenido incompleto o desactualizado. Por favor, añade cualquier documentación faltante para main. Asegúrate de revisar Edge Guides primero para verificar si los problemas ya están resueltos o no en la rama principal. Consulta las Directrices de las Guías de Ruby on Rails para el estilo y las convenciones.
Si por alguna razón encuentras algo que corregir pero no puedes solucionarlo tú mismo, por favor abre un problema.
Y por último, cualquier tipo de discusión sobre la documentación de Ruby on Rails es muy bienvenida en el Foro oficial de Ruby on Rails.