매개 변수가있는 before_filter


84

다음과 같은 방법이 있습니다.

before_filter :authenticate_rights, :only => [:show]

def authenticate_rights
  project = Project.find(params[:id])
  redirect_to signin_path unless project.hidden
end

다른 컨트롤러에서도이 방법을 사용하고 싶기 때문에이 방법을 application_controller에 포함 된 도우미에 복사했습니다.

문제는 일부 컨트롤러에서 프로젝트의 ID가 :id기호가 아니라 fe :project_id( :id다른 모델의 경우 a 도 있음)입니다.

이 문제를 어떻게 해결 하시겠습니까? before_filter 작업에 매개 변수를 추가하는 옵션이 있습니까 (오른쪽 매개 변수를 전달하기 위해)?

답변:


86

나는 다음과 같이 할 것입니다.

before_filter { |c| c.authenticate_rights correct_id_here }

def authenticate_rights(project_id)
  project = Project.find(project_id)
  redirect_to signin_path unless project.hidden
end

correct_id_here에 액세스하기위한 관련 ID는 어디에 있습니까 Project?


2
,:only => [:show]기호 를 추가하는 방법이 있습니까? 시도 중 오류가 발생합니다before_filter { |c| c.authenticate_rights correct_id_here }, :only => [:show]
choise

27
다른 방법으로 시도해보십시오 before_filter(:only => [:show]) { <block_code_here> }.. 여기에 더 많은 예제 : apidock.com/rails/ActionController/Filters/ClassMethods/...
fguillen

1
before_filterprivate 메서드 를 만들어서 보안을 설정 한 다음 리팩터링 (예 : 부모 컨트롤러, ApplicationController 등으로 이동) c.send(:filter_name, ...)하면 필터가 컨트롤러 컨텍스트에서 실행되지 않으므로을 사용해야 합니다. guides.rubyonrails.org/…
Richard Michael

2
이렇게하면 이름 (proc)이 없기 때문에 before_filter를 재정의 / 건너 뛸 수 없습니다. 전달하려는 값은 클래스 수준입니다. 가능합니까?
oreoshake

1
@oreoshake : 저도 같은 문제가 있습니다. 해결책을 찾았습니까?
marcus3006

67

일부 구문 설탕으로 :

before_filter -> { find_campaign params[:id] }, only: [:show, :edit, :update, :destroy]

또는 더 멋지게하기로 결정한 경우 :

before_filter ->(param=params[:id]) { find_campaign param }, only: %i|show edit update destroy|

그리고 before_action의 동의어 인 Rails 4 before_filter가 도입되었으므로 다음과 같이 작성할 수 있습니다.

before_action ->(param=params[:id]) { find_campaign param }, only: %i|show edit update destroy|

NB

->람다 리터럴lambda 이라고 하며 Ruby 1.9에서 소개합니다.

%i 기호 배열을 생성합니다.


5
이 답변은 '.send'를 사용하지 않고 클래스의 실행 컨텍스트에 람다 기본값, 따라서 private 메소드를 호출 할 수 있기 때문에 더 우아
데이비드 펠라

@Vadym Tyemirov find_campaign개인 메서드 이름입니까? 에서 param=params[:id], 인 param에 인수로 전달 될 새로운 지역 변수의 이름은 find_campaign? 의미, find_campaignprivate 메서드 자체 내에서 paramnot params{:id],?
ahnbizcad

1
find_campaign둘 중 하나 일 수 있지만, 소비되지 않는 것을 노출하지 않도록 비공개로 설정하겠습니다. params우리의 방법을 사용할 해시 변수가, param당신이 find_campaign 방법, 예를 전달해야 할 거라고 어떤 변수입니다before_action ->(campaign_id=params[:id]) { find_campaign(campaign_id) }, only: %i| show edit update destroy |
바딤 Tyemirov

14

@alex의 대답을 계속하려면 :except또는 :only일부 방법 을 원할 경우 구문은 다음과 같습니다.

before_filter :only => [:edit, :update, :destroy] do |c| c.authenticate_rights params[:id] end 

여기 에서 찾았 습니다 .


5

do...end가장 명확한 옵션 대신 중괄호를 사용하는 블록 방법을 찾습니다.

before_action(only: [:show]) { authenticate_rights(id) }

before_action 새로운 선호 구문입니다. before_filter


-1

이것은 작동합니다.

project = Project.find(params[:project_id] || params[:id])

이것은 반환해야 params[:project_id]는 PARAMS 해시에있는 경우, 또는 반환 params[:id]이되지 않습니다.


문제는 때로는 둘 다 존재 (중첩)되어 올바른 프로젝트가 아닌 프로젝트를 찾는 것입니다.
choise

@choise : 그런 일이 일어나지 않아야합니다. 만약 project_id존재 한다면 이 or절은 이것이 사용되도록 보장 할 것입니다 -a project_id가 제공되지 않은 경우에만 id매개 변수가 선택 될 것 입니다. 즉, 두 매개 변수가 모두 제공되면이 or절은 항상 선호하는대로 올바른 값이 사용되도록합니다 project_id. 당연히, 둘 다 존재 하지 않거나 존재하지 않지만 프로젝트를 참조하지 않는 project_id것이있을 때이 메서드를 호출하고 싶지 않을 것 id입니다.
Ola Tuvesson 2013 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.