NO LEA ESTE ARCHIVO EN GITHUB, LAS GUÍAS ESTÁN PUBLICADAS EN https://guides.rubyonrails.org.

Guías de Documentación de la API

Esta guía documenta las pautas de documentación de la API de Ruby on Rails.

Después de leer esta guía, sabrá:


1 RDoc

La documentación de la API de Rails se genera con RDoc. Para generarla, asegúrese de estar en el directorio raíz de rails, ejecute bundle install y ejecute:

$ bundle exec rake rdoc

Los archivos HTML resultantes se pueden encontrar en el directorio ./doc/rdoc.

NOTA: Consulte la Referencia de Marcado de RDoc para obtener ayuda con la sintaxis.

2 Enlaces

La documentación de la API de Rails no está destinada a ser vista en GitHub y, por lo tanto, los enlaces deben usar el marcado de enlace de RDoc relativo a la API actual.

Esto se debe a las diferencias entre el Markdown de GitHub y el RDoc generado que se publica en api.rubyonrails.org y edgeapi.rubyonrails.org.

Por ejemplo, usamos [link:classes/ActiveRecord/Base.html] para crear un enlace a la clase ActiveRecord::Base generada por RDoc.

Esto se prefiere sobre las URL absolutas como [https://api.rubyonrails.org/classes/ActiveRecord/Base.html], que llevarían al lector fuera de su versión actual de documentación (por ejemplo, edgeapi.rubyonrails.org).

3 Redacción

Escriba oraciones simples y declarativas. La brevedad es una ventaja. Vaya al grano.

# MALO
# El almacenamiento en caché puede interferir con la posibilidad de ver los resultados
# de los cambios en el código.

# BUENO
# El almacenamiento en caché interfiere con la visualización de los resultados de los cambios en el código.

Use tiempo presente:

# MALO
# Devuelve un hash que...
# Devolverá un hash que...
# Devuelva un hash que...

# BUENO
# Devuelve un hash que...

Comience los comentarios en mayúscula. Siga las reglas de puntuación habituales:

# MALO
# declara un lector de atributo respaldado por una variable de instancia
# nombrada internamente

# BUENO
# Declara un lector de atributo respaldado por una variable de instancia
# nombrada internamente.

Comunique al lector la forma actual de hacer las cosas, tanto explícita como implícitamente. Use los modismos recomendados en edge. Reordene secciones para enfatizar los enfoques favorecidos si es necesario, etc. La documentación debe ser un modelo de mejores prácticas y uso canónico y moderno de Rails.

# MALO
# Book.where('name = ?', "Donde viven los monstruos")
# Book.where('year_published < ?', 50.years.ago)

# BUENO
# Book.where(name: "Donde viven los monstruos")
# Book.where(year_published: ...50.years.ago)

La documentación debe ser breve pero completa. Explore y documente casos límite. ¿Qué sucede si un módulo es anónimo? ¿Qué pasa si una colección está vacía? ¿Qué pasa si un argumento es nulo?

3.1 Nombres

Los nombres propios de los componentes de Rails tienen un espacio entre las palabras, como "Active Support". ActiveRecord es un módulo Ruby, mientras que Active Record es un ORM. Toda la documentación de Rails debe referirse de manera coherente a los componentes de Rails por sus nombres propios.

# BUENO
# Las clases de Active Record se pueden crear heredando de
# ActiveRecord::Base.

Al referirse a una "aplicación Rails", en lugar de un "motor" o "plugin", siempre use "aplicación". Las aplicaciones de Rails no son "servicios", a menos que se discuta específicamente sobre arquitectura orientada a servicios.

# MALO
# Los servicios de producción pueden informar su estado aguas arriba.
# Devise es una aplicación de autenticación de Rails.

# BUENO
# Las aplicaciones de producción pueden informar su estado aguas arriba.
# Devise es un motor de autenticación de Rails.

Escriba correctamente los nombres de software. En caso de duda, consulte alguna fuente autorizada como su documentación oficial.

# BUENO
# Arel
# ERB
# Hotwire
# HTML
# JavaScript
# minitest
# MySQL
# npm
# PostgreSQL
# RSpec

Use el artículo "an" para "SQL":

# MALO
# Crea una declaración SQL.
# Inicia una base de datos SQLite.

# BUENO
# Crea una declaración SQL.
# Inicia una base de datos SQLite.

3.2 Pronombres

Prefiera redacciones que eviten "tú" y "tu".

# MALO
# Si necesitas usar declaraciones +return+ en tus callbacks, se recomienda
# que las definas explícitamente como métodos.

# BUENO
# Si se necesita +return+, se recomienda definir explícitamente un
# método.

Dicho esto, cuando use pronombres en referencia a una persona hipotética, como "un usuario con una cookie de sesión", deben usarse pronombres de género neutro (ellos/su). En lugar de:

  • él o ella... use ellos.
  • él o ella... use ellos.
  • su o sus... use su.
  • suyo o suya... use suyo.
  • él mismo o ella misma... use ellos mismos.

3.3 Inglés Americano

Por favor, use inglés americano (color, center, modularize, etc). Vea una lista de diferencias de ortografía entre inglés americano y británico aquí.

3.4 Coma de Oxford

Por favor, use la coma de Oxford ("rojo, blanco y azul", en lugar de "rojo, blanco y azul").

4 Código de Ejemplo

Elija ejemplos significativos que representen y cubran lo básico, así como puntos interesantes o trampas.

Para un renderizado adecuado, indente el código dos espacios desde el margen izquierdo. Los ejemplos en sí deben seguir las convenciones de codificación de Rails.

Los documentos cortos no necesitan una etiqueta "Ejemplos" explícita para introducir fragmentos; simplemente siguen a los párrafos:

# Convierte una colección de elementos en una cadena formateada llamando
# +to_s+ en todos los elementos y uniéndolos.
#
#   Blog.all.to_fs # => "Primer PostSegundo PostTercer Post"

Por otro lado, grandes fragmentos de documentación estructurada pueden tener una sección "Ejemplos" separada:

# ==== Ejemplos
#
#   Person.exists?(5)
#   Person.exists?('5')
#   Person.exists?(name: "David")
#   Person.exists?(['name LIKE ?', "%#{query}%"])

Los resultados de las expresiones los siguen y se introducen con "# => ", alineados verticalmente:

# Para verificar si un entero es par o impar.
#
#   1.even? # => false
#   1.odd?  # => true
#   2.even? # => true
#   2.odd?  # => false

Si una línea es demasiado larga, el comentario puede colocarse en la línea siguiente:

#   label(:article, :title)
#   # => <label for="article_title">Título</label>
#
#   label(:article, :title, "Un título corto")
#   # => <label for="article_title">Un título corto</label>
#
#   label(:article, :title, "Un título corto", class: "title_label")
#   # => <label for="article_title" class="title_label">Un título corto</label>

Evite usar métodos de impresión como puts o p para ese propósito.

Por otro lado, los comentarios regulares no usan una flecha:

#   polymorphic_url(record)  # igual que comment_url(record)

4.1 SQL

Al documentar declaraciones SQL, el resultado no debe tener => antes de la salida.

Por ejemplo,

#   User.where(name: 'Oscar').to_sql
#   # SELECT "users".* FROM "users" WHERE "users"."name" = 'Oscar'

4.2 IRB

Al documentar el comportamiento de IRB, el REPL interactivo de Ruby, siempre prefije los comandos con irb>. La salida debe estar precedida de =>.

Por ejemplo,

# Encuentra al cliente con clave primaria (id) 10.
#   irb> customer = Customer.find(10)
#   # => #<Customer id: 10, first_name: "Ryan">

4.3 Bash / Línea de Comandos

Para ejemplos de línea de comandos, siempre prefije el comando con $. La salida no tiene que estar precedida de nada.

# Ejecute el siguiente comando:
#   $ bin/rails new zomg
#   ...

5 Booleanos

Para predicados y banderas, prefiera documentar la semántica booleana sobre valores exactos.

Cuando se usan "true" o "false" como se definen en Ruby, use fuente regular. Los singletones true y false necesitan fuente de ancho fijo. Por favor, evite términos como "verdadero". Ruby define lo que es verdadero y falso en el lenguaje, y por lo tanto esas palabras tienen un significado técnico y no necesitan sustitutos.

Como regla general, no documente singletones a menos que sea absolutamente necesario. Eso previene constructos artificiales como !! o ternarios, permite refactorizaciones, y el código no necesita depender de los valores exactos devueltos por los métodos llamados en la implementación.

Por ejemplo:

# +config.action_mailer.perform_deliveries+ especifica si el correo
# realmente se entregará y es verdadero por defecto

el usuario no necesita saber cuál es el valor predeterminado real de la bandera, y por lo tanto solo documentamos su semántica booleana.

Un ejemplo con un predicado:

# Devuelve verdadero si la colección está vacía.
#
# Si la colección ha sido cargada, es equivalente a
# +collection.size.zero?+. Si la colección no ha sido cargada,
# es equivalente a +!collection.exists?+. Si la colección no
# ha sido cargada y va a buscar los registros de todos modos,
# es mejor verificar +collection.length.zero?+.
def empty?
  if loaded?
    size.zero?
  else
    @target.blank? && !scope.exists?
  end
end

La API se cuida de no comprometerse con ningún valor particular, el método tiene semántica de predicado, lo cual es suficiente.

6 Nombres de Archivos

Como regla general, use nombres de archivos relativos a la raíz de la aplicación: config/routes.rb en lugar de routes.rb o RAILS_ROOT/config/routes.rb.

7 Fuentes

7.1 Fuente de Ancho Fijo

Use fuentes de ancho fijo para:

  • Constantes, en particular nombres de clases y módulos
  • Nombres de métodos
  • Literales como nil, false, true, self
  • Símbolos
  • Parámetros de métodos
  • Nombres de archivos
  • Etiquetas y atributos HTML
  • Selectores CSS, atributos y valores
class Array
  # Llama a +to_param+ en todos sus elementos y une el resultado con
  # barras. Esto es usado por +url_for+ en Action Pack.
  def to_param
    collect { |e| e.to_param }.join '/'
  end
end

ADVERTENCIA: Usar +...+ para fuente de ancho fijo solo funciona con contenido simple como clases ordinarias, módulos, nombres de métodos, símbolos, rutas (con barras diagonales), etc. Use <tt>...</tt> para todo lo demás.

Puede probar rápidamente la salida de RDoc con el siguiente comando:

$ echo "+:to_param+" | rdoc --pipe
# => <p><code>:to_param</code></p>

Por ejemplo, el código con espacios o comillas debe usar la forma <tt>...</tt>.

7.2 Fuente Regular

Cuando "true" y "false" son palabras en inglés en lugar de palabras clave de Ruby, use una fuente regular:

# Ejecuta todas las validaciones dentro del contexto especificado.
# Devuelve verdadero si no se encuentran errores, falso de lo contrario.
#
# Si el argumento es falso (el valor predeterminado es +nil+), el contexto se
# establece en <tt>:create</tt> si <tt>new_record?</tt> es verdadero,
# y en <tt>:update</tt> si no lo es.
#
# Las validaciones sin opción <tt>:on</tt> se ejecutarán sin importar el contexto.
# Las validaciones con alguna opción <tt>:on</tt> solo se ejecutarán en el contexto especificado.
def valid?(context = nil)
  # ...
end

8 Listas de Descripción

En listas de opciones, parámetros, etc., use un guion entre el elemento y su descripción (se lee mejor que un dos puntos porque normalmente las opciones son símbolos):

# * <tt>:allow_nil</tt> - Omite la validación si el atributo es +nil+.

La descripción comienza en mayúscula y termina con un punto: es inglés estándar.

Un enfoque alternativo, cuando desea proporcionar detalles adicionales y ejemplos, es usar el estilo de sección de opciones.

ActiveSupport::MessageEncryptor#encrypt_and_sign es un gran ejemplo de esto.

# ==== Opciones
#
# [+:expires_at+]
#   La fecha y hora en la que expira el mensaje. Después de esta fecha y hora,
#   la verificación del mensaje fallará.
#
#     message = encryptor.encrypt_and_sign("hola", expires_at: Time.now.tomorrow)
#     encryptor.decrypt_and_verify(message) # => "hola"
#     # 24 horas después...
#     encryptor.decrypt_and_verify(message) # => nil

9 Métodos Generados Dinámicamente

Los métodos creados con (module|class)_eval(STRING) tienen un comentario a su lado con una instancia del código generado. Ese comentario está a 2 espacios del template:

(module|class)_eval(STRING) comentarios de código

Si las líneas resultantes son demasiado anchas, digamos 200 columnas o más, coloque el comentario encima de la llamada:

# def self.find_by_login_and_activated(*args)
#   options = args.extract_options!
#   ...
# end
self.class_eval %{
  def self.#{method_id}(*args)
    options = args.extract_options!
    ...
  end
}, __FILE__, __LINE__

10 Visibilidad de Métodos

Al escribir documentación para Rails, es importante diferenciar entre la API orientada al usuario y la API interna.

Los métodos que están en el ámbito privado de Ruby están excluidos de la API orientada al usuario. Sin embargo, algunos métodos de la API interna deben estar en el ámbito público de Ruby para que puedan ser llamados en otras partes del marco. Para excluir dichos métodos de la API orientada al usuario, use la directiva :nodoc: de RDoc.

Un ejemplo es ActiveRecord::Core::ClassMethods#arel_table:

module ActiveRecord::Core::ClassMethods
  def arel_table # :nodoc:
    # hacer algo mágico...
  end
end

Aunque es un método público, los usuarios no deben confiar en él. El nombre de este método puede cambiar, o el valor de retorno puede cambiar, o este método puede ser eliminado por completo. Al marcarlo con :nodoc:, se elimina de la documentación de la API orientada al usuario.

Como contribuyente, es importante pensar si una API debe ser orientada al usuario o interna. El equipo de Rails se compromete a no realizar cambios significativos en la API orientada al usuario sin antes pasar por un ciclo completo de desaprobación. Por lo tanto, debe agregar :nodoc: a cualquier método o módulo interno, a menos que ya sean privados. (Agregar :nodoc: a un módulo o clase indica que todos los métodos son API internos, y debe eliminarse de la documentación de la API orientada al usuario).

11 Con respecto a la Pila de Rails

Al documentar partes de la API de Rails, es importante tener en cuenta toda la pila de Rails. El comportamiento del método o clase que está documentando puede cambiar dependiendo del contexto.

Un ejemplo de esto es ActionView::Helpers::AssetTagHelper#image_tag:

# image_tag("icon.png")
#   # => <img src="/assets/icon.png" />

En aislamiento, image_tag devolvería /images/icon.png. Sin embargo, cuando tenemos en cuenta toda la pila de Rails, incluido el Pipeline de Activos, podemos ver el resultado anterior.

Queremos documentar el comportamiento del marco, no solo métodos aislados. Nuestra preocupación es el comportamiento que el usuario experimenta al usar toda la pila de Rails predeterminada.

Si tiene alguna pregunta sobre cómo maneja el equipo de Rails ciertas API, no dude en abrir un ticket o enviar un parche al rastreador de problemas.


Comentarios

Se te anima a ayudar a mejorar la calidad de esta guía.

Por favor contribuye si ves algún error tipográfico o errores fácticos. Para comenzar, puedes leer nuestra sección de contribuciones a la documentación.

También puedes encontrar contenido incompleto o cosas que no están actualizadas. Por favor agrega cualquier documentación faltante para main. Asegúrate de revisar Guías Edge primero para verificar si los problemas ya están resueltos o no en la rama principal. Revisa las Guías de Ruby on Rails para estilo y convenciones.

Si por alguna razón detectas algo que corregir pero no puedes hacerlo tú mismo, por favor abre un issue.

Y por último, pero no menos importante, cualquier tipo de discusión sobre la documentación de Ruby on Rails es muy bienvenida en el Foro oficial de Ruby on Rails.