Mam metodę, która robi coś takiego:
before_filter :authenticate_rights, :only => [:show]
def authenticate_rights
project = Project.find(params[:id])
redirect_to signin_path unless project.hidden
end
Chcę również użyć tej metody w niektórych innych kontrolerach, więc skopiowałem metodę do pomocnika, który jest zawarty w application_controller.
problem polega na tym, że w niektórych kontrolerach id projektu nie jest :id
symbolem, ale fe :project_id
(a także :id
występuje a (dla innego modelu)
Jak rozwiązałbyś ten problem? czy istnieje opcja dodania parametru do akcji before_filter (w celu przekazania odpowiedniego parametru)?
,:only => [:show]
symbolu?before_filter { |c| c.authenticate_rights correct_id_here }, :only => [:show]
before_filter(:only => [:show]) { <block_code_here> }
. Więcej przykładów tutaj: apidock.com/rails/ActionController/Filters/ClassMethods/…before_filter
metody prywatnej, a następnie możesz ponownie uwzględnić (np. Przenieść ją do kontrolera nadrzędnego, ApplicationController itp.), Będziesz musiał użyć,c.send(:filter_name, ...)
ponieważ filtr nie będzie działał w kontekście kontrolera. guide.rubyonrails.org/…Z odrobiną cukru syntaktycznego:
before_filter -> { find_campaign params[:id] }, only: [:show, :edit, :update, :destroy]
Lub jeśli zdecydujesz się na jeszcze bardziej wymyślny:
before_filter ->(param=params[:id]) { find_campaign param }, only: %i|show edit update destroy|
A ponieważ Rails 4
before_action
, synonim nazwybefore_filter
, został wprowadzony, można to zapisać jako:before_action ->(param=params[:id]) { find_campaign param }, only: %i|show edit update destroy|
NB
->
oznaczalambda
, zwany literałem lambda , wprowadzony w Rubim 1.9%i
utworzy tablicę symboliźródło
find_campaign
nazwa metody prywatnej? Wparam=params[:id]
,param
czy nazwa nowej zmiennej lokalnej, która zostanie przekazana jako argument dofind_campaign
? Co oznacza, że wfind_campaign
samej metodzie prywatnej, używamyparam
nieparams{:id]
?find_campaign
może być albo, ale uczyniłbym to prywatnym, aby mieć pewność, że nie ujawnimy tego, co nie jest skonsumowane.params
jest zmienną hash dostępną dla naszych metod,param
jest dowolną zmienną, którą trzeba przekazać do metody find_campaign, np.before_action ->(campaign_id=params[:id]) { find_campaign(campaign_id) }, only: %i| show edit update destroy |
Aby kontynuować odpowiedź @alex, jeśli chcesz
:except
lub:only
niektóre metody, oto składnia:before_filter :only => [:edit, :update, :destroy] do |c| c.authenticate_rights params[:id] end
Znaleziono tutaj .
źródło
Uważam, że metoda blokowa używa nawiasów klamrowych zamiast
do...end
być najwyraźniejszą opcjąbefore_action(only: [:show]) { authenticate_rights(id) }
before_action
jest po prostu nowszą preferowaną składnią dlabefore_filter
źródło
To powinno działać:
project = Project.find(params[:project_id] || params[:id])
Powinien powrócić,
params[:project_id]
jeśli jest obecny w hashu params, lub zwrócić,params[:id]
jeśli nie jest.źródło
project_id
jest obecna,or
klauzula zapewni, że zostanie to użyte - tylko jeśliproject_id
nie zostanieid
podany parametr, zostanie wybrany. Innymi słowy: gdy podane są oba parametry,or
klauzula zapewnia użycie poprawnej wartości, co zawsze będzie preferowaneproject_id
. Oczywiście nie chcesz wywoływać tej metody, gdy żadna z nich nie jest obecna lub gdy nie ma,project_id
ale istnieje,id
która nie odwołuje się do projektu.