Cuando se establece un before_filter
, o cualquier filtro similar (piensan after_filter
, around_filter
), por lo que estás haciendo, ya sea con un Symbol o una Proc, lambda o bloque.
before_filter :bark
before_filter Proc.new { |k| k.bark }
Lo anterior añade los símbolos o bloques para una pila here, llamando set_callback
. Esto construye la 'cadena' a la que se refiere.
Cada elemento de esta 'cadena' es una instancia de la clase ActiveSupport::Callbacks::Callback
. Esta clase sabe
- El método (símbolo) o bloque debe ejecutar (es decir. La clase
:bark
método)
- El contexto que debería ejecutarse dentro (es decir. La clase
Dog
)
Los Callback
casos se añaden a un ActiveSupport::Callbacks::CallbackChain
en __update_callbacks
.
Cuando se inicializa cada clase Callback
, _compile_filter
se ejecuta para normalizar el filtro de la Symbol
, Proc
, lambda, o bloquear en un formato común, invocable.
Por último, cuando se ejecuta el CallbackChain
, se llamará start
en cada Callback
ejemplo, y su en este punto que el filtro se ejecuta realmente en el contexto adecuado.
Es importante señalar que a usted le no crear un filtro como
before_filter dog.bark
esto va a ejecutar dog.bark
y pasar su valor de retorno a before_filter
que se anexará a la CallbackChain
. La intención es pasar algún tipo de instrucción al before_filter
para que los rieles se ejecuten más tarde. Se podría hacer algo como lugar
before_filter Proc.new { d = Dog.new; d.bark }
El código dentro del Proc
no se ejecuta. cuando la línea de arriba es ejecutada por Rails. En cambio, se le dice a Rails que pase el Proc
al CallbackChain
. El Proc
es la 'instrucción' que le está pasando a Rails para que se ejecute en el momento apropiado.
cómo en el primer lugar no raíles saben que he llamado: Corteza
En cuanto a esto, digamos que su clase Dog
se define simplemente como
class Dog
def bark
end
def eat
end
end
(Aunque este es un terrible ejemplo), es posible que desee tener algo como
before_bark :eat
Para ello, debe definir la devolución de llamada bark
, y luego a su método de bark
para ejecutar los relacionados bark
devoluciones de llamada.
class Dog
extend ActiveModel::Callbacks
define_callbacks :bark
before_bark :eat
def bark
run_callbacks(:bark) { YOUR BARK CODE HERE }
end
def eat
end
end
Puedes ver cómo ActiveRecord::Callbacks
hace esto.
Esto realmente es un mal ejemplo porque puedes (y deberías) simplemente llamar al eat
directamente desde bark
, pero esto debería aclarar el punto.
¡Gracias al principio! Pero aún confusión. Usted dijo 'Finalmente, cuando se ejecuta el CallbackChain ...', y mi pregunta es ¿cómo sabe exactamente que los rieles deben ejecutarse CallbackChain? Diga, si configuro before_filter: eat to class Dog. Luego, cuando llame a dog.bark,: eat debería ejecutarse primero. Pero, ¿cómo sabe en primer lugar que he llamado: ladrar? – HanXu
Actualicé mi respuesta. – deefour
Mucho más claro, pero todavía un poco confundido. En su ejemplo, redefinimos ladrar manualmente, pero los rieles lo hacen automáticamente por algún código. No encuentro dónde están estos códigos. Según @harald, los rieles han modificado cada acción por adelantado. Noté 'attr_internal' en AbstractController :: Base, ¿hay magia? – HanXu