9. Form 헬퍼

2020. 6. 11. 11:13Rails 5 on aws c9

지금까지는 우리가 주소를 입력하면 페이지가 뜨게 하는 방법을 배웠다

이제는 서버에 입력값을 전달하는법을 배워보겠다.

먼저 contacts 컨트롤러를 하나 생성해보겠다.

ubuntu:~/environment/hello_world (master) $ rails g controller Contacts index new create

Running via Spring preloader in process 25315
      create  app/controllers/contacts_controller.rb
      invoke  erb
      create    app/views/contacts
      invoke  test_unit
      create    test/controllers/contacts_controller_test.rb
      invoke  helper
      create    app/helpers/contacts_helper.rb
      invoke    test_unit
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/contacts.coffee
      invoke    scss
      create      app/assets/stylesheets/contacts.scss

이렇게하면 자동으로 함수들도 같이 생성된다. view들도 자동으로 생성됐다.

라우트 규칙도 자동으로 추가된것을 볼 수 있다.

레이아웃 파일에 가서 메뉴를 수정해보자

/contact → /contacts/new

contact를 누르면 다음과 같이 나오는걸 볼 수 있다.

그럼 이 상태에서 form tag를 작성해보도록 하겠다

app/views/contacts/new.html.erb

<form action="/contacts/create" methd="get">
    Name : <input type="text" name="name"><br>
    Email : <input type="email" name="email"><br>
    Content : <textarea name="content"></textarea><br>
    <input type="submit">
</form>

여기서 말하는 액션은 이 폼의 내용을 작성하고 전송버튼을 누르면 결과값을 받아줄 주소를 쓴것.

contacts 컨트롤러에 create라는 액션을 만들었기 때문에 그쪽에서 값을 받을 수 있게 되고 그 방식은 get방식이다.

저장하고 새로고침하면 다음과같이 나온다

내용을 다음과 같이 채우고 제출을 누르면

contacts create로 넘어가고, 주소를 보면 ? 뒤에 아까 입력한 값들이 넘어온것을 볼 수 있다.

key 와 value로 이루어짐을 볼 수 있다. 이런걸 파라미터라고한다.

여기까지 했으면

컨트롤러에서 이렇게 파라미터로 전달한 값을 받아보도록 하겠다.

new에서 값을 입력하고 전송을 클릭하면

create 액션에서 받는걸 확인할 수 있었다.

파라미터를 받는 방법은 @로 받을 수 있다.

comper 를 입력했으면 @name엔 comper가 저장된다.

그리고 이렇게 @로 받은값을 뷰에서 쓸 수 있다.

class ContactsController < ApplicationController
  def index
  end

  def new
  end

  def create
    @name = params[:name]
    @email = params[:email]
    @content = params[:content]
  end
end

다음과 같이 받아서 출력해보자

방금 전달된 값들이 화면에 출력되는걸 볼 수 있다.

new에서 작성한 값을 create에서 받게되고, 그걸 create view 에서 보여줄 수 있게된다.

그런데 이렇게하면 주소창의 내용만 바꿔도, 내용이 바뀔것이라 예상할 수 있다. 실제로도 그렇다.

비밀번호같은게 이렇게 찍히면 보안이 취약해질것을 예상할 수 있다.

혹은 주소창에 들어가기에 양이 너무 많을수 있다.

그럼 get방식 대신 post방식을 이용하면 된다.

views/contacts/new.html.erb 수정 (get→post)

<form action="/contacts/create" methd="***post***">
    Name : <input type="text" name="name"><br>
    Email : <input type="email" name="email"><br>
    Content : <textarea name="content"></textarea><br>
    <input type="submit">
</form>

config/routes.rb 수정 (get→post)(이걸 안해주면 라우팅 에러가 뜬다)

Rails.application.routes.draw do
  get 'contacts/index'

  get 'contacts/new'

  ***post 'contacts/create'***

    get '/' => 'home#hello_world' 
    get '/index' => 'home#index'
    get '/contact' => 'home#contact'
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

그러고 실행하면 에러가 뜬다...

이 에러는 엑션컨트롤러에서 AuthenticityToken이 없다는거다

이는 csrf공격을 방지하기 위한 방법이다

무작위공격같은걸 막기 위함이다

이를 작동하지 않게 하려면

여기서 protect_from_forgery를 없애면 되지만 보안상의 문제를 일으킨다.

form 태그를 레일즈에서 제공하는 form 헬퍼로 바꿔보도록 하겠다.

헬퍼는 간단한 루비코드로 복잡한 html 코드를 작성할 수 있게 도와주는것이다.

다음과 같이 코드를 작성해보자

여기서 post방식 대신 get방식을 쓰고싶다면 <%= form_tag "/contacts/create", method: 'get' do %> 라고 하면 된다.

<%= form_tag "/contacts/create" do %>
    Name : <input type="text" name="name"><br>
    Email : <input type="email" name="email"><br>
    Content : <textarea name="content"></textarea><br>
    <input type="submit">
<% end %>

태그를 쓰면서 자동으로 추가된 코드를 볼 수 있다.

<input type="hidden" name="authenticity_token" value="l6oTUW2m2cs0H3I4oCq7KaXtYB8JhzDRYNEEsg3iWL7JDBOnKF/od5+I47GDqH3pluRsGrDQZU42bL87iB4HZg==">