레일스 액션 뷰 폼 헬퍼

 Biweekly Lecture

2015-11-03, 11-17

Ruby on Rails Korea

- ROR Lab. Season 4 -

살펴볼 내용

폼 헬퍼의 목적은 쉽고 편한 마크업

  • 모델에 연결하지 않거나 검색 등 일반 폼 form_tag, xxx_field_tag
  • 모델에 연결하여 데이터베이스에서 레코드를 생성, 편집 form_for
  • 여러 종류의 데이터를 선택 select_tag
  • 레일스의 일자, 시간 헬퍼 time_zone, country_select, select_date
  • 서버로 파일 업로드 file_field_tag
  • 외부로 전송하는 폼
  • 복잡한 폼을 작성하는 방법

form_tag

  • form_tag(url_for_options = {}, options = {}, &block)
    • url_for_options: 라우트의 콘트롤러 액션 주소
    • options: 
      • method(verb): GET, POST, PUT, DELETE, PATCH
      • multi-part: “multipart/form-data” 설정
      • authenticity_token: 인증에 사용할 토큰 설정
      • remote, enforce_utf8
      • html 속성
form_tag('/posts')   # => <form action="/posts" method="post">
form_tag('/posts/1', method: :put)  # => <form action="/posts/1" method="post"> 
... <input name="_method" type="hidden" value="put" /> ...
form_tag('/upload', multipart: true) # => <form action="/upload" method="post" enctype=
"multipart/form-data">
<%= form_tag('/posts') do -%> <div><%= submit_tag 'Save' %></div> <% end -%>
# => <form action="/posts" method="post"><div><input type="submit" name="commit" value=
"Save" /></div></form>
<%= form_tag('/posts', remote: true) %>  # => <form action="/posts" method="post" data-remote=
"true">
form_tag('http://far.away.com/form', authenticity_token: false) # form without 
authenticity token
form_tag('http://far.away.com/form', authenticity_token: "cf50faa3fe97702ca1ae")
# form with custom authenticity token
<form action="/general/test" accept-charset="UTF-8" method="post">
<input name="utf8" type="hidden" value="✓">
<input type="hidden" name="authenticity_token" 
value="YJUk/sXdPJWKZl1rQDzIOckEP1J0ExqchuFCEP3H7Eh6zMppZ5hICd2eai
+eQ7l+U9ye1XxjZYGQyXmaX52KFA==">
basic form tag
</form>
<%= form_tag { 'basic form tag' } %>
  • basic form: 문자열 인코딩은 UTF-8, CSRF(Cross-Site Request Forgery) 보안
<form action="/search" accept-charset="UTF-8" method="get">
  <input name="utf8" type="hidden" value="✓">
  <label for="q">Search for:</label>
  <input type="text" name="q" id="q">
  <input type="submit" name="commit" value="Search">
</form>
<%= form_tag("/search", method: "get") do %>
  <%= label_tag(:q, "Search for:") %>
  <%= text_field_tag(:q) %>
  <%= submit_tag("Search") %
<% end %>
  • search form:
    • get 메소드 url 기록: http://localhost:3000/search?utf8=%E2%9C%93&q=sometext&commit=Search
  • 옵션: url_option과 option은 둘 다 해시이며 {} 사용, 마지막 파라미터는 해시
<form action="/people/search?class=nifty_form&method=get" 
accept-charset="UTF-8" method="post">
<input name="utf8" type="hidden" value="✓">
<input type="hidden" name="authenticity_token" 
value="+nsMItVWu4EXlnQJI+YKqLM8enklQvKoM1AK9iNf3cvgIuK1dxPPHU
BuQ039mXvvKeTb/i0yjbUleDF8gQW7lw==">
not used to hash bracket
</form>
<%= form_tag(controller: "people", action: "search", method: "get", 
class: "nifty_form") { 'not used to hash bracket' } %>
<%= form_tag({controller: "people", action: "search"}, method: "get", 
class: "nifty_form") { 'hash bracket' } %>
<form class="nifty_form" action="/people/search" 
accept-charset="UTF-8" method="get">
<input name="utf8" type="hidden" value="✓">
hash bracket
</form>
  • 체크박스(복수 선택)와 라디오 버튼(택일)
<form action="/general/test" accept-charset="UTF-8" method="post">
<input name="utf8" type="hidden" value="✓">
<input type="hidden" name="authenticity_token" 
value="uJmzTzFlXCd/zqEM9nxuhUb7v+Hgr9HWkGrki2uq632iw
F3YkyAouyg2lkgoAx/C3CMeZujfrsuGQt8ByfCNIQ==">
<input type="checkbox" name="pet_dog" id="pet_dog" value="1">
<label for="pet_dog">I own a dog</label>
<input type="checkbox" name="pet_cat" id="pet_cat" value="1">
<label for="pet_cat">I own a cat</label>
<input type="radio" name="age" id="age_child" value="child">
<label for="age_child">I am younger than 21</label>
<input type="radio" name="age" id="age_adult" value="adult">
<label for="age_adult">I'm over 21</label>
</form>
<%= form_tag do %>
<%= check_box_tag(:pet_dog) %>
<%= label_tag(:pet_dog, "I own a dog") %>
<%= check_box_tag(:pet_cat) %>
<%= label_tag(:pet_cat, "I own a cat") %>
<%= radio_button_tag(:age, "child") %>
<%= label_tag(:age_child, "I am younger than 21") %>
<%= radio_button_tag(:age, "adult") %>
<%= label_tag(:age_adult, "I'm over 21") %>
<% end %>

폼 태그 헬퍼 안에 사용할 필드 헬퍼

  • password fields
  • hidden fields
  • search fields
  • telephone fields
  • date fields
  • time fields
  • color fields
  • datetime fields
  • datetime-local fields
  • month fields
  • week fields
  • URL fields
  • email fields
  • number fields
  • range fields
  • 비밀번호(환경설정에서 로그 필터 설정)
  • 토큰같은 정보 전달
  • 검색어
  • 전화번호
  • 일자
  • 시간
  • 색깔
  • 일시
  • 지역별 일시
  • 연간중 월
  • 몇 주차
  • URL 주소
  • 이메일 주소
  • 수(숫자)
  • 슬라이드로 범위 설정

HTML5 태그 사용하기 위해 폴리필(html5shiv 자바스크립트 브라우저 기능보완)

gem 'modernizr-rails' <%= javascript_include_tag :modernizr %> 

<form action="/general/test" accept-charset="UTF-8" method="post">
<input name="utf8" type="hidden" value="✓"><input type="hidden" name="authenticity_token" 
value="dA/ruDKU8UeRDQLovYjetYRhQS9ZH0FJ92MsJxopEURuVgUvkNGF28b1Naxj96/yHrngqFFvPlThSxetuHN3GA==">
<textarea name="message" id="message" cols="24" rows="6">Hi, nice site</textarea>
<input type="password" name="password" id="password">
<input type="hidden" name="parent_id" id="parent_id" value="5">
<input type="search" name="user[name]" id="user_name">
<input type="tel" name="user[phone]" id="user_phone">
<input type="date" name="user[born_on]" id="user_born_on">
<input type="datetime" name="user[meeting_time]" id="user_meeting_time">
<input type="datetime-local" name="user[graduation_day]" id="user_graduation_day">
<input type="month" name="user[birthday_month]" id="user_birthday_month">
<input type="week" name="user[birthday_week]" id="user_birthday_week">
<input type="url" name="user[homepage]" id="user_homepage">
<input type="email" name="user[address]" id="user_address">
<input value="#000000" type="color" name="user[favorite_color]" id="user_favorite_color">
<input type="time" name="task[started_at]" id="task_started_at">
<input step="0.5" min="1.0" max="20.0" type="number" name="product[price]" id="product_price">
<input min="1" max="100" type="range" name="product[discount]" id="product_discount">
</form>
<%= form_tag do %>
<%= text_area_tag(:message, "Hi, nice site", size: "24x6") %>
<%= password_field_tag(:password) %>
<%= hidden_field_tag(:parent_id, "5") %>
<%= search_field(:user, :name) %>
<%= telephone_field(:user, :phone) %>
<%= date_field(:user, :born_on) %>
<%= datetime_field(:user, :meeting_time) %>
<%= datetime_local_field(:user, :graduation_day) %>
<%= month_field(:user, :birthday_month) %>
<%= week_field(:user, :birthday_week) %>
<%= url_field(:user, :homepage) %>
<%= email_field(:user, :address) %>
<%= color_field(:user, :favorite_color) %>
<%= time_field(:task, :started_at) %>
<%= number_field(:product, :price, in: 1.0..20.0, step: 0.5) %>
<%= range_field(:product, :discount, in: 1..100) %>
<% end %>

form_for

  • form_for(record, options = {}, &block) 
    • record: 심볼, 인스턴스변수, 로컬변수
    • options: 
      • url: 라우트 경로, 지정하지 않으면 해당 객체 주소를 유추
      • namespace: 그룹 지정하여 아이디 구분
      • method(verb): GET, POST, PUT, DELETE, PATCH
      • authenticity_token: 인증에 사용할 토큰 설정
      • remote, enforce_utf8, html 속성(style)
<%= form_for :person do |f| %>
  First name: <%= f.text_field :first_name %><br />
  Last name : <%= f.text_field :last_name %><br />
  Biography : <%= f.text_area :biography %><br />
  Admin?    : <%= f.check_box :admin %><br />
  <%= f.submit %>
<% end %>
<form action="/general/test" accept-charset="UTF-8" method="post">
<input name="utf8" value="✓" type="hidden"><input name="authenticity_token" 
value="hE....oVouRlJGXayOjidVw==" type="hidden">
  First name: <input name="person[first_name]" id="person_first_name" type="text"><br>
  Last name : <input name="person[last_name]" id="person_last_name" type="text"><br>
  Biography : <textarea name="person[biography]" id="person_biography"></textarea><br>
  Admin?    : <input name="person[admin]" value="0" type="hidden"><input value="1" name="person[admin]" 
id="person_admin" type="checkbox"><br>
  <input name="commit" value="Save Person" type="submit">
</form>
<input name="person[name]" id="person_name" type="text">
<%= text_field(:person, :name) %>
  • basic form: person 모델의 name 속성에 대한 입력 폼
<% @article = Article.new %>
<%= form_for @article do |f| %>
  instance value
<% end %>
<%= form_for(@article, as: :client) do |f| %>
  as option
<% end %>
<% test_article = Article.new %>
<%= form_for test_article do |f| %>
  local variable
<% end %>
<form class="new_article" id="new_article" action="/articles" 
accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" />
<input type="hidden" name="authenticity_token" value="" />
  instance value
</form>
<form class="new_client" id="new_client" action="/articles" 
accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" />
<input type="hidden" name="authenticity_token" value="" />
  as option
</form>
<form class="new_article" id="new_article" action="/articles" accept-charset="UTF-8" 
method="post"><input name="utf8" type="hidden" value="✓" />
<input type="hidden" name="authenticity_token" value="" />
  local variable
</form>
  • form_for 유형: 라우트에 있는 경로를 유추함
<%= form_for @article, url: {action: "create"}, html: {class: "nifty_form"} do |f| %>
  <%= f.text_field :title %>
  <%= f.text_area :body, size: "60x12" %>
  <%= f.submit "Create" %>
<% end %>
class ArticlesController < ApplicationController
  before_action :set_article, only: [:show, :edit, :update, :destroy]
  # GET /articles/new
  def new
    @article = Article.new
  end
  • basic form: person 모델의 name 속성에 대한 입력 폼
$ rails g scaffold article title:string body:text
  • app/controllers/articles_controller.rb
  • app/views/articles/new.html.erb 또는 _form.html.erb
<form class="nifty_form" id="new_article" action="/articles" accept-charset="UTF-8"
 method="post">
<input name="utf8" value="✓" type="hidden">
<input name="authenticity_token" 
value="kApzFL4Rek9HYxI0wnNSk63sLAi6hRKiQTr6xBBcSd4W84pVWZs5j0xrbokvgvBis
R028JFHaV63lo96KM/sfg==" type="hidden">
  <input name="article[title]" id="article_title" type="text">
  <textarea name="article[body]" id="article_body" cols="60" rows="12"></textarea>
  <input name="commit" value="Create" type="submit">
</form>
class ArticlesController < ApplicationController
  before_action :set_article, only: [:show, :edit, :update, :destroy]
  # POST /articles
  def create
    @article = Article.new(article_params)
    
    redirect_to @article, notice: "#{params.inspect}"
  end
  • app/controllers/articles_controller.rb
{ 
  "utf8"=>"✓", 
  "authenticity_token"=>"W9W1kmsmBM3Rf2GW511CM1NCuwGUjhdDNEdLCzLsHOrdLEzTjKx
HDdp3HSsKrODCT7Oh+b9MbL/C6z61Cn+5Sg==", 
  "article"=>{"title"=>"", "body"=>""}, 
  "commit"=>"Create", 
  "controller"=>"articles", 
  "action"=>"create"
}
<% @person = Person.new %>
<% @person.build_contact %>
<%= form_for @person, url: { controller: "person", action: "create" } 
do |person_form| %>
  <%= person_form.text_field :name %>
    <%= fields_for @person.contact do |contact_form| %>
    <%= contact_form.text_field :telephone %>
  <% end %>
  <%= person_form.submit %>
<% end %>
  • fields_for: Person(name, age) has_one Contact(address, telephone)
<form class="new_person" id="new_person" action="/person" 
accept-charset="UTF-8" method="post"><input name="utf8" 
value="✓" type="hidden">
<input name="authenticity_token" value="vmOVvPOghiSiF0iamWvnFYhR+wyt3UFrjI
njz2uxalM4mmz9FCrF5KkfNCd0mkXklKDh9IYfOpd6JZZxUyLP8w==" type="hidden">
  <input name="person[name]" id="person_name" type="text">
    
    <input name="contact[telephone]" id="contact_telephone" type="text">
  <input name="commit" value="Create Person" type="submit">
</form>

모델관계에 따라 입력 폼 작성

중첩(Nested Form): 
설문조사(Survey),문항(Question),선택지(Answer) 

accepts_nested_attributes_for

  • accepts_nested_attributes_for(*attr_names)
    • :allow_destroy => _destroy = true (1, '1', true, 'true) 인 항목 삭제
    • :reject_if => 프록 또는 심볼(메소드)로 비어있거나 조건에 따라 항목 삭제
    • :limit => 추가할 항목 개수 제한
    • :update_only => 1 대 1 관계에서만 유효 
class Question < ActiveRecord::Base
  belongs_to :survey
  has_many :answers, :dependent => :destroy
  accepts_nested_attributes_for :answers, reject_if: proc { |a| a['content'].blank? }, allow_destroy: true
end
<div class="field">
  <%= f.label :name %><br>
  <%= f.text_field :name %>
<%= f.fields_for :questions do |builder| %>
  <%= render 'question_fields', f: builder %>
<% end %>
</div>
<p>
  <%= f.label :content, "Question" %><br />
  <%= f.text_area :content, rows: 3 %><br />
  <%= f.check_box :_destroy %>
  <%= f.label :_destroy, "Remove Question" %>
</p>
<%= f.fields_for :answers do |builder| %>
  <%= render 'answer_fields', f: builder %>
<% end %>

<p>
  <%= f.label :content, "Answer" %>
  <%= f.text_field :content %>
  <%= f.check_box :_destroy %>
  <%= f.label :_destroy, "Remove" %>
</p>
<p>
  <%= f.label :content, "Answer" %>
  <%= f.text_field :content %>
  <%= f.check_box :_destroy %>
  <%= f.label :_destroy, "Remove" %>
</p>
  <label for="survey_questions_attributes_0_content">Question</label><br>
  <textarea rows="3" name="survey[questions_attributes][0][content]" 
id="survey_questions_attributes_0_content"></textarea><br>
  <input name="survey[questions_attributes][0][_destroy]" type="hidden" value="0">
<input type="checkbox" value="1" name="survey[questions_attributes][0][_destroy]" 
id="survey_questions_attributes_0__destroy">
  <label for="survey_questions_attributes_0__destroy">Remove Question</label>

  <label for="survey_questions_attributes_0_answers_attributes_0_content">Answer</label>
  <input type="text" name="survey[questions_attributes][0][answers_attributes][0][content]" 
id="survey_questions_attributes_0_answers_attributes_0_content">
  <input name="survey[questions_attributes][0][answers_attributes][0][_destroy]" 
type="hidden" value="0"><input type="checkbox" value="1" 
name="survey[questions_attributes][0][answers_attributes][0][_destroy]" 
id="survey_questions_attributes_0_answers_attributes_0__destroy">
  <label for="survey_questions_attributes_0_answers_attributes_0__destroy">Remove</label>

  <label for="survey_questions_attributes_0_answers_attributes_1_content">Answer</label>
  <input type="text" name="survey[questions_attributes][0][answers_attributes][1][content]" 
id="survey_questions_attributes_0_answers_attributes_1_content">
  <input name="survey[questions_attributes][0][answers_attributes][1][_destroy]" 
type="hidden" value="0"><input type="checkbox" value="1" 
name="survey[questions_attributes][0][answers_attributes][1][_destroy]" 
id="survey_questions_attributes_0_answers_attributes_1__destroy">
  <label for="survey_questions_attributes_0_answers_attributes_1__destroy">Remove</label>

  <label for="survey_questions_attributes_0_answers_attributes_2_content">Answer</label>
  <input type="text" name="survey[questions_attributes][0][answers_attributes][2][content]" 
id="survey_questions_attributes_0_answers_attributes_2_content">
  <input name="survey[questions_attributes][0][answers_attributes][2][_destroy]" 
type="hidden" value="0"><input type="checkbox" value="1" 
name="survey[questions_attributes][0][answers_attributes][2][_destroy]" 
id="survey_questions_attributes_0_answers_attributes_2__destroy">
  <label for="survey_questions_attributes_0_answers_attributes_2__destroy">Remove</label>

  <label for="survey_questions_attributes_0_answers_attributes_3_content">Answer</label>
  <input type="text" name="survey[questions_attributes][0][answers_attributes][3][content]" 
id="survey_questions_attributes_0_answers_attributes_3_content">
  <input name="survey[questions_attributes][0][answers_attributes][3][_destroy]" 
type="hidden" value="0"><input type="checkbox" value="1" 
name="survey[questions_attributes][0][answers_attributes][3][_destroy]" 
id="survey_questions_attributes_0_answers_attributes_3__destroy">
  <label for="survey_questions_attributes_0_answers_attributes_3__destroy">Remove</label>

select_tag

  • select_tag(name, option_tags = nil, options = {})
    • name: html 태그 요소 이름
    • option_tags: options_from_collection_for_select, <option...>
    • options: 
      • multiple: true 이면 2개 이상 선택가능
      • disabled: 선택하지 못하도록 음영처리
      • include_blank: true이면 빈칸을 만들고 문자열이면 선택안할 때 사용
      • prompt: 알림 메시지 표시
      • html 태그 요소
<%= select_tag(:city_id, '<option value="1">Lisbon</option><option value="2">Paris</option>'.html_safe) %>
<% @cities = City.all %>
<%= select_tag "cities", options_from_collection_for_select(@cities, "id", "name") %>
<%= select_tag "cities", options_from_collection_for_select(@cities, "id", "name", "1") %>
<%= select_tag "cities", "<option>Seoul</option>".html_safe %>
<%= select_tag "count", "<option>1</option><option>2</option><option>3</option><option>4</option>".html_safe %>
<%= select_tag "colors", "<option>Red</option><option>Green</option><option>Blue</option>".html_safe, 
multiple: true %>
<%= select_tag "locations", "<option>Home</option><option selected='selected'>Work</option>
<option>Out</option>".html_safe %>
<%= select_tag "access", "<option>Read</option><option>Write</option>".html_safe, multiple: true, 
class: 'form_input', id: 'unique_id' %>
<%= select_tag "cities", options_from_collection_for_select(@cities, "id", "name"), 
include_blank: true %>
<%= select_tag "cities", options_from_collection_for_select(@cities, "id", "name"), 
include_blank: "All" %>
<%= select_tag "cities", options_from_collection_for_select(@cities, "id", "name"), 
prompt: "Select something" %>
<%= select_tag "destination", "<option>NYC</option><option>Paris</option><option>Rome</option>".html_safe, 
disabled: true %>
<%= select_tag "credit_card", options_for_select([ "VISA", "MasterCard" ], "MasterCard") %>

options_xxx_for_select

  • options_for_select(container, selected = nil)
    • container: 해시, 배열, 이뉴머러블
    • selected: 미리 선택할 옵션
<%= options_for_select([["Dollar", "$"], ["Kroner", "DKK"]]) %>
<%= options_for_select([ "VISA", "MasterCard" ], "MasterCard") %>
<%= options_for_select({ "Basic" => "$20", "Plus" => "$40" }, "$40") %>
<%= options_for_select([ "VISA", "MasterCard", "Discover" ], ["VISA", "Discover"]) %>
  • options_from_collection_for_select(collection, value_method, text_method, selected = nil)
    • collection: 예) cities = City.all 이뉴머러블
    • value_method: 옵션의 값으로 사용할 메소드 이름
    • text_method: 옵션으로 표시할 텍스트로 사용할 메소드 이름
    • selected: 미리 선택할 옵션
<%= options_from_collection_for_select(@cities, 'id', 'name') %>

<% cities_array = City.all.map { |city| [city.name, city.id] } %>
<%= options_for_select(cities_array) %>

select 객체 연결

  • select(object, method, choices = nil, options = {}, html_options = {}, &block)
    • object: 폼 빌더
    • method: 필드 이름
    • choices: 옵션 목록
#1
<% @article = Article.new() %>
<% @cities = City.all %>
<%= form_for @article do |f| %>
  <%= f.select :title, options_from_collection_for_select(@cities, 'id', 'name') %>
<% end %>

#2
<%= select :article, :title, options_from_collection_for_select(@cities, 'id', 'name') %>
#1
<form class="new_article" id="new_article" action="/articles" 
accept-charset="UTF-8" method="post">
<input name="utf8" type="hidden" value="✓">
<input type="hidden" name="authenticity_token" value="nIhylPf3...t3w==">
  <select name="article[title]" id="article_title">
<option value="1">Seoul</option><option value="2">Sejong</option>
<option value="3">Jeju</option><option value="4">Pyeongchang</option></select>
</form>

#2
<select name="article[title]" id="article_title"><option value="1">Seoul</option>
<option value="2">Sejong</option>
<option value="3">Jeju</option>
<option value="4">Pyeongchang</option></select>

collection_select 객체 연결

  • collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
    • object: 객체/ 폼 빌더사용
    • method: 필드 이름
    • collection: 옵션 목록  value_method: 옵션값  text_method:옵션표시
#1
<%= form_for @article do |f| %>
<%= f.collection_select(:title, City.all, :id, :name) %>
<% end %>

#2
<%= collection_select(:article, :title, City.all, :id, :name) %>
#1
<form class="new_article" id="new_article" action="/articles" 
accept-charset="UTF-8" method="post">
<input name="utf8" type="hidden" value="✓"><input type="hidden" 
name="authenticity_token" value="Peaax...g=="><select name="article[title]" 
id="article_title">
<option value="1">Seoul</option><option value="2">Sejong</option>
<option value="3">Jeju</option><option value="4">Pyeongchang</option></select>
</form>

#2
<select name="article[title]" id="article_title"><option value="1">Seoul</option>
<option value="2">Sejong</option>
<option value="3">Jeju</option>
<option value="4">Pyeongchang</option></select>

시간 관련 헬퍼

  • time_zone_select(사용), country_select(젬 설치)
  • select_date(태그 사용), date_select(폼 빌더 사용)
<%= time_zone_select( "article", "title", nil, include_blank: true) %>
<% @article = Article.new %>
<%= form_for @article do |f| %>
<%= f.time_zone_select(:title, nil, include_blank: true) %>
<% end %>
<br/>
<%= select_date Date.today, prefix: :start_date %>
<%= form_for @article do |f| %>
<%= f.date_select(:title) %>
<% end %>
<select name="article[title]" id="article_title"><option value=""></option>
<option value="American Samoa">(GMT-11:00) American Samoa</option>
<option value="International Date Line West">(GMT-11:00) International Date Line West</option>
<option value="Seoul">(GMT+09:00) Seoul</option>
<option value="Tokelau Is.">(GMT+13:00) Tokelau Is.</option></select>

<form class="new_article" id="new_article" action="/articles" 
accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓">
<input type="hidden" name="authenticity_token" 
value="..../ig==">
<select name="article[title]" id="article_title"><option value=""></option>
<option value="American Samoa">(GMT-11:00) American Samoa</option>
<option value="Seoul">(GMT+09:00) Seoul</option>
<option value="Tokelau Is.">(GMT+13:00) Tokelau Is.</option></select>
</form>

<select id="start_date_year" name="start_date[year]">
<option value="2010">2010</option>...
<option value="2015" selected="selected">2015</option>
...<option value="2020">2020</option>
</select>
<select id="start_date_month" name="start_date[month]">
<option value="1">January</option>
<option value="2">February</option>
...
<option value="11" selected="selected">November</option>
<option value="12">December</option>
</select>
<select id="start_date_day" name="start_date[day]">
<option value="1">1</option>
...
<option value="31">31</option>
</select>

<form class="new_article" id="new_article" action="/articles" 
accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓">
<input type="hidden" name="authenticity_token" 
value="BO...g==">
<select id="article_title_1i" name="article[title(1i)]">
<option value="2010">2010</option>
<option value="2015" selected="selected">2015</option>
<option value="2020">2020</option>
</select>
<select id="article_title_2i" name="article[title(2i)]">
<option value="1">January</option>
<option value="10">October</option>
<option value="12">December</option>
</select>
<select id="article_title_3i" name="article[title(3i)]">
<option value="1">1</option>
<option value="19">19</option>
<option value="31">31</option>
</select>
</form>
<select id="start_date_year" name="start_date[year]">
<option value="2010">2010</option>...# 현재 연도 전후 5년
<option value="2015" selected="selected">2015</option>
...<option value="2020">2020</option>
</select>
<select id="start_date_month" name="start_date[month]">
<option value="1">January</option>
<option value="2">February</option>
...
<option value="11" selected="selected">November</option>
<option value="12">December</option>
</select>
<select id="start_date_day" name="start_date[day]">
<option value="1">1</option>
...
<option value="31">31</option>
</select>

<form class="new_article" id="new_article" action="/articles" 
accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓">
<input type="hidden" name="authenticity_token" 
value="BO...g==">
<select id="article_title_1i" name="article[title(1i)]">
<option value="2010">2010</option>
<option value="2015" selected="selected">2015</option>
<option value="2020">2020</option>
</select>
<select id="article_title_2i" name="article[title(2i)]">
<option value="1">January</option> # 2월의 경우에도 31일까지 나타남
<option value="10">October</option>
<option value="12">December</option>
</select>
<select id="article_title_3i" name="article[title(3i)]">
<option value="1">1</option>
<option value="19">19</option>
<option value="31">31</option>
</select>
</form>

파일 업로드 관련 헬퍼

  • file_field_tag, "multipart/form-data"  필요
<%= form_tag({action: :upload}, multipart: true) do %>
  <%= file_field_tag 'picture' %>
<% end %>
 
<% @article = Article.new %> # multipart 생략 가능
<%= form_for @article, url: article_upload_path(@article) do |f| %>
  <%= f.file_field :picture %>
  <%= f.submit "upload" %>
<% end %>

  def upload
    uploaded_io = params[:article][:picture]
    File.open(Rails.root.join('public', 'uploads', uploaded_io.original_filename), 'wb') do |file|
      file.write(uploaded_io.read)
    end
    redirect_to general_upload_path
  end
<form enctype="multipart/form-data" action="/general/upload" 
accept-charset="UTF-8" method="post">
<input name="utf8" type="hidden" value="✓"><input type="hidden" 
name="authenticity_token" value="wz....==">
  <input type="file" name="picture" id="picture">
</form> 
<form class="new_article" id="new_article" enctype="multipart/form-data" 
action="/articles/upload" accept-charset="UTF-8" method="post">
<input name="utf8" type="hidden" value="✓"><input type="hidden" 
name="authenticity_token" value="wz...SPrhQ==">
  <input type="file" name="article[picture]" id="article_picture">
  <input type="submit" name="commit" value="upload">
</form>
def upload
  uploaded_io = params[:article][:picture]
  File.open(Rails.root.join('public', 'uploads', uploaded_io.original_filename), 
'wb') do |file|
    file.write(uploaded_io.read)
  end
  redirect_to general_upload_path
end

파일 업로드 젬

# app/form_builders/labelling_form_builder.rb
class LabellingFormBuilder < ActionView::Helpers::FormBuilder
  def text_field(attribute, options={})
    label(attribute) + super
  end
end

# app/views/general/builder.html.erb
<% @article = Article.new %>
<%= form_for @article, builder: LabellingFormBuilder do |f| %>
  <%= f.text_field :title %>
<%= render f, world: "hello" %>
<% end %>

# app/views/general/_labelling_form.html.erb
partial: <%= world %>
<form class="new_article" id="new_article" action="/articles" 
accept-charset="UTF-8" method="post">
<input name="utf8" type="hidden" value="✓">
<input type="hidden" name="authenticity_token" 
value="5wMz2...">
  <label for="article_title">Title</label><input type="text" 
name="article[title]" id="article_title">
partial: hello
</form>

Text

폼 빌더 활용

Made with Slides.com