-
Notifications
You must be signed in to change notification settings - Fork 4
Rails Avanzado
Por defecto Rails viene con WEBBrick
, el problema de este es que no es concurrente. Como consecuencia es un mal candidato para entornos de production.
Existen múltiples alternativas, en este caso se sugerirá usar Puma
Cabe mencionar que requiere un poco de configuración para hacer que el servidor de la app empiece con Puma. Una opción es usar Foreman tanto para development y production, este último depende de cómo sea el deployment.
Estar generando los HTML
y JSON
(para el caso de las API) para cada solicitud puede resultar costo para el servidor pues necesita estar consultando constantemente la base de datos y generando archivos. Esto puede ser ineficiente si sabemos que las requests más recurrentes apuntan a recursos que cambian poco en el tiempo.
Más información en: http://edgeguides.rubyonrails.org/caching_with_rails.html
Supongamos un recurso Person
que tiene una asociación has_many :jobs
y con datos suficientes para este ejemplo.
Al hacer lo siguiente, estamos haciendo dos consultas a la base de datos:
Person.find_by_id(42).jobs
Consultas efectuadas pre-optimización:
- La primera es para encontrar a la persona con
id
igual a42
. - La segunda es para encontrar los
jobs
asociados a esa persona.
A esto se le llama el problema de N+1 queries.
Sería ideal poder efectuar todo eso en una simple consulta. Para esto usamos eager_load
:
Person.eager_load(:jobs).find_by_id(42).jobs
Con esto solo estamos haciendo solo una sola consulta 👌
Una gema útil para detectar cuando usar eager_loading
es bullet
Uno puede cargar más relaciones, por ejemplo:
Person.eager_load(:jobs, :proyects, :boss).find_by_id(42).jobs
¿Qué pasa si necesitamos crear, por ejemplo, comentarios para n
modelos para una red social? Sería un caos tener que crear n
tablas llamadas comments_modelo1
, comments_modelo2
, ..., comments_modelon
.
Para evitar esto, creamos solo un solo modelo comments
y le asociamos un belongs_to: commentable, polymorphic: true
.
Podemos crear la migración manualmente, o podemos usar el generador:
rails g model Comment user:references commentable:references{polymorphic}
Debemos tener algo así como migración:
create_table :comments do |t|
# ...
t.references :commentable, polymorphic: true, index: true
# ...
end
En los modelos "comentables" les declaramos:
class Comment < ActiveRecord::Base
belongs_to :user
belongs_to :commentable, polymorphic: true
end
class Foto < ActiveRecord::Base
has_many :comments, as: :commentable
end
class Video < ActiveRecord::Base
has_many :comments, as: :commentable
end
Más información en: http://guides.rubyonrails.org/association_basics.html#polymorphic-associations