본문 바로가기
Programming/Ruby On Rails

[Ruby On Rails] before_action 및 after_action 사용법과 실행 순서

by 가론노미 2023. 6. 17.

Rails에서는 컨트롤러의 메서드 실행 직전 또는 직후에 특정한 작업을 처리하기 위해

before_action, after_action, around_action을 사용할 수 있다.

 

세 가지 필터 모두 기본적인 사용법은 아래와 같다. 관례적으로 컨트롤러의 상단에 정의해 준다.

UserController 내의 정의된 모든 public 메서드 실행 직전에 require_login이 먼저 실행되게 된다.

class UserController < ActionController::Base
  before_action :require_login
end

특정 액션에서만 사용하기

only를 사용할 경우 특정 액션에서만 before_action이 실행된다.

class UserController < ActionController::Base
  before_action :require_login, only: %w[index show]
end

특정 액션에서만 제외하기

except를 사용할 경우 컨트롤러 내에서 특정 액션만 제외하고 before_action이 실행된다.

class UserController < ActionController::Base
  before_action :require_login, except: :create
end

실행 순서

before_action, after_action, around_action 사용법은 모두 동일하지만, 이름에서 유추할 수 있듯이 각각 실행 순서가 다르다.

 

먼저 before_action은 메서드 실행 직전에 처리된다.

동일한 메서드에 여러 before_action이 추가된 경우 정의된 순서대로 위에서부터 처리되는 것을 볼 수 있다.

class UserController < ActionController::Base
  before_action -> { puts "Calling before_action 1" }
  before_action -> { puts "Calling before_action 2" }
end
Calling before_action 1
Calling before_action 2

 

after_action은 before_action과 반대로 메서드 실행 직후에 처리된다.

주의할 점은 after_action은 동일한 메서드에 여러 after_action이 추가된 경우 정의된 순서의 반대로 아래서부터 처리된다는 것이다.

class UserController < ActionController::Base
  after_action -> { puts "Calling after_action 1" }
  after_action -> { puts "Calling after_action 2" }
end
Calling after_action 2
Calling after_action 1

 

around_action은 before_action과 after_action을 묶어서 사용하는 것이라고 볼 수 있다.

yield가 메서드 실행 시점이며 yield 앞의 코드는 before_action과 같고, yield 뒤의 코드는 after_action과 같다.

class UserController < ActionController::Base
  around_action :around_action_test
  around_action :around_action_test2
  
  def around_action_test
	puts 'Calling around_action 1 - before yield'
    yield
    puts 'Calling around_action 1 - after yield'
  end

  def around_action_test2
    puts 'Calling around_action 2 - before yield'
    yield
    puts 'Calling around_action 2 - after yield'
  end
end
Calling around_action 1- before yield
Calling around_action 2 - before yield
# yield
Calling around_action 2 - after yield
Calling around_action 1 - after yield