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 :idsímbolo sino fe :project_id(y también :idestá 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_filtermé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_actionquebefore_filterse 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%icreará una matriz de símbolosfuente
find_campaignel nombre del método privado? Enparam=params[:id], ¿esparamel nombre de la nueva variable local que se le pasará como argumentofind_campaign? Es decir, que dentro delfind_campaignmétodo privado en sí, usamosparamno,params{:id]?find_campaignpodría ser cualquiera, pero lo haría privado para asegurarnos de no exponer lo que no se consume.paramses una variable hash disponible para nuestros métodos,parames 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
:excepto:onlyalgunos métodos, aquí está la sintaxis:before_filter :only => [:edit, :update, :destroy] do |c| c.authenticate_rights params[:id] endEncontrado aquí .
fuente
Encuentro que el método de bloqueo usa llaves en lugar de
do...endser la opción más clarabefore_action(only: [:show]) { authenticate_rights(id) }before_actiones solo la sintaxis preferida más reciente parabefore_filterfuente
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_idestá presente, laorcláusula garantizará que se use; solo siproject_idno se proporciona a,idse seleccionará el parámetro. En otras palabras: cuando se suministran ambos parámetros, laorclá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_idpero hay unidque no hace referencia a un proyecto.