Tengo un método que hace algo como esto:
before_filter :authenticate_rights, :only => [:show]
def authenticate_rights
project = Project.find(params[:id])
redirect_to signin_path unless project.hidden
end
También quiero usar este método en algunos otros controladores, así que copié el método en un ayudante que se incluye en application_controller.
el problema es que, en algunos controladores, la identificación del proyecto no es el :id
símbolo sino fe :project_id
(y también :id
está presente (para otro modelo)
Como resolverías este problema? ¿Existe una opción para agregar un parámetro a la acción before_filter (para pasar el parámetro correcto)?
,:only => [:show]
símbolo? Recibo un error al intentarlobefore_filter { |c| c.authenticate_rights correct_id_here }, :only => [:show]
before_filter(:only => [:show]) { <block_code_here> }
. Más ejemplos aquí: apidock.com/rails/ActionController/Filters/ClassMethods/…before_filter
método sea privado, entonces quizás vuelva a factorizar (por ejemplo, muévalo a un controlador principal, ApplicationController, etc.), deberá usarloc.send(:filter_name, ...)
ya que el filtro no se ejecutará en el contexto del controlador. guides.rubyonrails.org/…Con algo de azúcar sintáctico:
before_filter -> { find_campaign params[:id] }, only: [:show, :edit, :update, :destroy]
O si decides ponerte aún más elegante:
before_filter ->(param=params[:id]) { find_campaign param }, only: %i|show edit update destroy|
Y desde
before_action
quebefore_filter
se introdujo Rails 4 , un sinónimo de , se puede escribir como:before_action ->(param=params[:id]) { find_campaign param }, only: %i|show edit update destroy|
nótese bien
->
significalambda
, llamado lambda literal , introducir en Ruby 1.9%i
creará una matriz de símbolosfuente
find_campaign
el nombre del método privado? Enparam=params[:id]
, ¿esparam
el nombre de la nueva variable local que se le pasará como argumentofind_campaign
? Es decir, que dentro delfind_campaign
método privado en sí, usamosparam
no,params{:id]
?find_campaign
podría ser cualquiera, pero lo haría privado para asegurarnos de no exponer lo que no se consume.params
es una variable hash disponible para nuestros métodos,param
es cualquier variable que deba pasar al método find_campaign, por ejemplobefore_action ->(campaign_id=params[:id]) { find_campaign(campaign_id) }, only: %i| show edit update destroy |
Para continuar con la respuesta de @alex, si lo desea
:except
o:only
algunos métodos, aquí está la sintaxis:before_filter :only => [:edit, :update, :destroy] do |c| c.authenticate_rights params[:id] end
Encontrado aquí .
fuente
Encuentro que el método de bloqueo usa llaves en lugar de
do...end
ser la opción más clarabefore_action(only: [:show]) { authenticate_rights(id) }
before_action
es solo la sintaxis preferida más reciente parabefore_filter
fuente
Esto debería funcionar:
project = Project.find(params[:project_id] || params[:id])
Esto debería regresar
params[:project_id]
si está presente en el hash de params, o regresarparams[:id]
si no lo está.fuente
project_id
está presente, laor
cláusula garantizará que se use; solo siproject_id
no se proporciona a,id
se seleccionará el parámetro. En otras palabras: cuando se suministran ambos parámetros, laor
cláusula asegura que se utilice el valor correcto, como siempre se preferiráproject_id
. Naturalmente, no querrá llamar a este método cuando ninguno de los dos está presente, o cuando no hayproject_id
pero hay unid
que no hace referencia a un proyecto.