개발자 노트

[정리]Action Controller 본문

Web/Rails

[정리]Action Controller

jurogrammer 2020. 8. 14. 00:21

출처

1. Controller의 역할

일반적인 MVC모델에서 역할과 레일즈에서 개발자가 개발할 일

라우터가 url요청을 보고 어떤 컨트롤러가 해당 요청을 수행할 지 결정한 다음, 해당 컨트롤러는 아래와 같은 사항을 책임지고 있다.

  1. 컨트롤러는 요청을 이해하는 역할
  2. 적절한 결과를 생산하는 역할

레일즈 컨트롤러도 일반적인 웹 컨트롤러처럼 작동. (request받고, 데이터를 저장소에서 가져오거나, 저장하고, layout을 전달해주기 위해 view 객체를 이용하고...) 뷰에게 모델 데이터를 전송해주므로 중간자라고 말할 수있음.

한편으로, Action Controller가 기초 작업을 다 해주므로, 레일즈 개발자는 똑똑한 컨벤션만 이용하면 됨.

2. Controller Naming Convention

레일즈 네이밍 컨벤션

복수형 선호

  • ex:)ClientsController, SiteAdminsController

컨벤션 따를 시 장점

  1. path, controller 설정해줄 필요없이, default route generators 사용 가능
  2. route helpers' usage 일정하게 유지.
    • Laayouts & Rendering Guide보면 잘 나와있음.

cf.) Model Naming Convention은 단수형 선호

3. Methods and Actions

  • controller는 Ruby class다.

  • 이 class는 ApllicationController 상속받음.

    • 상속받음으로써 메소드 존재
  • application이 request를 받으면, 라우팅은 어떤 컨트롤러에서 어떤 액션을 실행해야할 지 결정.

  • 결정했다면, Rails는 컨트롤러 인스턴스를 생성하고, 액션과 동일한 method를 실행.

  • 아래처럼 메소드가 비어있다 하더라도, default 설정으로 view에 있는 new.html.erb를 rendering하게 되어있음.

    class ClientsController < ApplicationController
      def new
      end
    end
  • 인스턴스 변수를 선언한다면, view에서 접근가능함.

    def new
      @client = Client.new
    end

    cf.) scope => client : 지역변수, @client : 인스턴스 변수, @@client : 클래스 변수

  • ApplicationController는 ActionController::Base를 상속
    • 다양한 메서드 지원

4. Parameters

파라미터 사용 용도

  1. 유저가 보낸 데이터 접근하기 위해
  2. 다른 컨트롤러의 action에서 보낸 데이터에 접근하기 위해.

파라미터의 종류

  1. Query string parameters

    • url을 통해 보내진 파라미터
  2. Post data

    • 유저가 html의 form에 작성한 데이터가 보내짐

    • Post를 통해서만 보내질 수 있어서 Post data라고 불림.

Rails의 두 파라미터 접근

구분안함!

params hash를 통해서 접근가능

1) Hash and Array Parameters

get방식으로 array 보내기 가능.

GET /clients?ids[]=1&ids[]=2&ids[]=3
  • 실제로 보내질 땐 아래와 같이 보내짐.

    /clients?ids%5b%5d=1&ids%5b%5d=2&ids%5b%5d=3
  • url encoding하기 때문에. brower는 자동으로 encoding해주고, rails는 자동으로 decoding함. 따라서 이에 대해 걱정할 필요 없음.

    • 하지만, 직접 보낼 땐 해당 사항을 참고할 것.
  • response의 params 형태

    The value of params[:ids] will now be ["1", "2", "3"]
    • url은 string이므로 string으로 변환되어 보내짐. rails에서 자동으로 converting하지 않음.

Hash로도 보낼 수 있음.

2) Json parameters

사용 방법

request의 header에서 Content-Typeapplication/json으로 정한다면, Rails는 자동으로 params hash를 통해서 접근 가능.

3) Routing Parameters

params가 가지고 있는 값

  • :controller, :action
    • 하지만 이 두 값은 controller_name 또는 action_name 메소드를 통해 접근할 수 있음.

routing에 의해 정해진 값

  • 동일하게 params를 통해 접근 가능

    get '/clients/:status', to: 'clients#index', foo: 'bar'

    request가 /clients/active일 경우

    • params[:status]의 값은 active로 setting.

    • params[:foo] 값 또한 'bar'로 setting. query parameter로 보내진 것 처럼 설정하는 것.

    • controller또한 parmas[:action] = "index"로 설정 (to: clinets#index)

    • params[:controller] = "clients"로 설정.

    cf.) /clients/:status 로 보내지면 client 컨트롤러 인스턴스를 생성하고, 해당 인스턴스의 index 메소드를 실행하세요!

5) Strong Parameters

Action Controller parameters가 Action Model 메세징먼트에서 사용 불가. (단, 허용해주면 사용가능)

의도

  • mass update를 위해 관심을 가지고 업데이트 하도록 하는 것. (mass update가 뭐여)

  • 이는 사용자가 모델을 업데이트하는 것을 방지하도록 두는 것.

  • 허용된 파라미터를 모두 받지 못하면 error 내도록 설정

    5.1)Permitted Values

    scala

    params.permit(:id)

    id가 scala value만 받도록 설정하는 것.

    나머지 값들은 모두 필터링되어 id에 값을 넣을 수 없음.

    hash

    params.permit(preferences: {})

    array

    params.permit(id: [])

    모두

    params.require(:log_entry).permit!

5~6제외 추후 필요하면 내용 추가

7. Rendering XML and JSON data

class UsersController < ApplicationController
  def index
    @users = User.all
    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render xml: @users }
      format.json { render json: @users }
    end
  end
end

object가 string이 아니라면, format.json에서 보듯이 자동으로 @users.to_json 해줌.

8. Filters

적용 범위

Filters는 상속되므로 ApplicationController에 적용한다면 모든 controller에서 작동됨.

종류

  1. before_action

    • applicationController에 아래와 같이 설정하여 사용 가능.
    class ApplicationController < ActionController::Base
      before_action :require_login
    
      private
    
      def require_login
        unless logged_in?
          flash[:error] = "You must be logged in to access this section"
          redirect_to new_login_url # halts request cycle
        end
      end
    end

    이렇게 설정한다면 모든 controller 접속시 login되었는지 확인함.

    • before_action 제외

      만약에 회원가입하는 화면에서도 login 되었는지 확인한다면 문제될 것. 따라서 create, new에 한해서는 아래처럼 제외 가능

      class LoginsController < ApplicationController
        skip_before_action :require_login, only: [:new, :create]
      end
  2. After Filters

    before filters와 달리 이미 action이 실행되었기 때문에 response data에 접근할 수 있음

    afterfilters는 실행중인 action을 멈출 수 없음.

    주의!

    request 사이클에서 에러가 났을 때 실행되는 것이 아니라 action이 성공적으로 실행되었을 때 after filters가 실행됨.

  1. Around Filters

    yield를 통해서 associated actions을 실행하는 것에 책임이 있음.

    Rack middlewares가 동작하는 방식과 유사.

    ex)

    class ChangesController < ApplicationController
      around_action :wrap_in_transaction, only: :show
    
      private
    
      def wrap_in_transaction
        ActiveRecord::Base.transaction do
          begin
            yield
          ensure
            raise ActiveRecord::Rollback
          end
        end
      end
    end

    rendering 도 감쌈.

9,10 추후 작성

11. HTTP Authentications

11.1 HTTP Basic Authentication

user가 아이디와 비밀번호를 입력하면 해당 아이디 비밀번호를 인증하는 방식

ex)

class AdminsController < ApplicationController
  http_basic_authenticate_with name: "humbaba", password: "5baa61e4"
end

위는 admins라는 namespace를 생성하여 이 admins를 상속받는 controller만 동작하도록 설정.

method는 위처럼 http_basic_authenticate_with 사용

11.2 HTTP Digest Authentication

http digest자체가 뭔지 잘 몰라서 패스.

반응형
Comments