DB설정
우선 CRUD를 구현하기 위해서 필요한 것이 DB입니다.
Ruby On Rails 환경설정할 때,
gem install sqlite3
명령어를 통해서 sqlite3 DB를 설치를 한 적이 있는데
Gemfile을 확인해보면
gem 'sqlite3', '~> 1.4'
파일에 추가되어있는 것을 볼 수 있습니다.
rails-db
하지만, DB를 시각적으로 보고 관리하기 위해서 필요한 것이 있습니다.
rails-db를 설치해야 하는데
https://rubygems.org/ 싸이트에서
rails-db를 검색하여 우측에 보이는 GEMFILE에 있는 코드를 복사합니다.
복사한 코드를 gemfile에 추가해줍니다.
gem 'rails_db', '~> 2.4', '>= 2.4.1'
빌드
bundle install
방금 gemfile에 추가한 rails_db 라이브러리를 우리의 rails 프로젝트에 추가해서 사용하기 위해서는 빌드작업이 필요합니다.
위의 명령어를 입력하면, 자동적으로 빌드작업을 해줍니다.
그러면, 이젠 DB를 시각적으로 어떻게 확인하는지?! Rails 서버의 기본 로컬주소에 /rails/db를 붙히면 된다.
localhost:3000/rails/db
그럼 메인 화면에서 테이블도 선택할 수 있고
테이블의 상세내용도 시각적으로 쉽게 관리할 수 있습니다.
테이블 생성
MVC구조에서 M인 model이 DB와의 접근을 담당하고 있기 때문에, 새로운 model을 생성해야 한다.
rails g model posts
위의 명령어를 실행하면, model폴더에 새롭게 post라는 파일과, db의 migration 폴더에 posts라는 파일이 생김
migration/posts.rb
class CreatePosts < ActiveRecord::Migration[6.1]
def change
create_table :posts do |t|
t.string :title
t.text :description
t.timestamps
end
end
end
위의 코드는 새로운 테이블을 만들고, 그 테이블의 속성을 선언을 해줍니다,
title이라는 속성명으로 타입은 string
description이라는 속성명으로 타입은 text
timestamps는 created_at과 updated_at 속성을 자동적으로 생성을 해줍니다.
그러면, 선언한 테이블을 실제로 DB에 적용하기 위해서는
rake db:migrate
위의 명령어를 실행합니다.
CRUD - C(create)
Form생성
이젠 사용자의 입력값을 받아서 DB에 저장하는 CRUD에서 C(create)를 구현하기 위한 Form이 필요합니다.
routes.rb
get "/home" => "blog#index"
URL이 "/home"일 경우에 blog controller의 index 함수를 실행한다.
blog_controller.rb
class BlogController < ApplicationController
def index
end
end
views/blog/index.erb
<%= form_tag "/create", method: :post do %>
<label for="title">제목</label>
<input type="text" name="title" /><br />
<label for="description">내용</label>
<input type="text" name="description" />
<button type="submit">제출</button>
<% end %>
조금 낯선 문법인데, 위는 rails에서 제공하는 폼헬퍼를 이용하여 form태그를 만든 것 입니다,
왜? 이렇게 만들었는지는 rails 6버전 부터는 CSRF공격을 막기위해서 Authenticity Token라는 것을 사용합니다.
사용자가 GET 이외의 PUT / POST / DELETE (내용을 수정할 수있는 메소드) 요청을 하면 사용자가 제출하는 form의 숨겨진 필드에도 authenticity_token이 저장됩니다.
서버는 액션을 실행하기 전에 폼 안의 authenticity_token과 세션에 저장된 authenticity_token를 비교해서 유효성을 검증합니다. 두 토큰이 같지 않으면 요청을 실행하지 않습니다.
그래서, authenticity_token을 지정해줘야 하는데, 위의 폼헬퍼를 사용하면, 자동적으로 만들어주는 것이고 위의 방법 말고도 다양한 방법이 존재합니다.
참고문헌 : https://haereeroo.tistory.com/2
그럼 "/home" URL로 접속하면, 제목과 내용을 입력할 수 있는 폼이 정상적으로 만들어진 것을 확인 할 수 있습니다.
DB에 저장
위의 폼태그를 보면, 제출하게 될 때 "/create"로 전송하는 것을 볼 수 있습니다.
routes.rb
post "/create" => "blog#create"
"/create"일 경우에는 blog controller의 create 함수를 실행
controllers/blog_controller.rb
def create
post = Post.new
post.title = params[:title]
post.description = params[:description]
post.save
redirect_to '/home'
end
post = Post.new 는 post 모델의 인스턴스를 하나 생성을 합니다.
그리고 post 테이블에서 속성값들인 title값과 description 값을 form태그에서 받아온 값으로 저장을 합니다.
여기서 form태그에서 보낸 값을 받는 방법으로는 params[:파라미터 이름] 형태로 받아 올 수 있습니다.
그리고 마지막으로 "post.save"를 통해서 DB에 실질적으로 저장이 되게 됩니다.
그리고 redirect_to 를 이용하면, 지정한 주소로 브라우저를 refresh 시킬 수 있습니다.
그러면, 제목과 내용을 작성하고 제출을 눌러보면
다시 "/home"화면으로 refresh되는 것을 확인할 수 있습니다.
그리고 "rails/db"로 가서 posts테이블을 확인해보면, 방금 작성한 내용이 DB에 저장된 것을 확인할 수 있습니다.
form 빌더
<%= form_with model: @article do |form| %>
<div>
<%= form.label :title %><br>
<%= form.text_field :title %>
</div>
<div>
<%= form.label :body %><br>
<%= form.text_area :body %>
</div>
<div>
<%= form.submit %>
</div>
<% end %>
빌더를 사용하여 최소한의 코드를 작성하여 완전히 구성되고 Rails 규칙을 따르는 양식을 출력할 수 있습니다.
<form action="/articles" accept-charset="UTF-8" method="post">
<input type="hidden" name="authenticity_token" value="...">
<div>
<label for="article_title">Title</label><br>
<input type="text" name="article[title]" id="article_title">
</div>
<div>
<label for="article_body">Body</label><br>
<textarea name="article[body]" id="article_body"></textarea>
</div>
<div>
<input type="submit" name="commit" value="Create Article" data-disable-with="Create Article">
</div>
</form>
위의 코드를 HTML코드로 변환하면 위와 같은 코드와 같아집니다.
strong typing
form태그를 통해서 받은 data는 params를 통해서 받아올 수 있지만, 이대로 받아오게 된다면 나쁜용도로 악용하고자 하는 사람들에게 이용당할 수 있다.
이것을 해결하기 위해서 strong typing이라는 강력한 매개변수를 통해 params를 필터링합니다.
def create
@article = Article.new(article_params)
if @article.save
redirect_to @article
else
render :new
end
end
private
def article_params
params.require(:article).permit(:title, :body)
end
article_params를 private로 따로 선언해주어 strong typing 처리를 해줍니다.
검증(validate)
Model/Article.rb
class Article < ApplicationRecord
validates :title, presence: true
validates :body, presence: true, length: { minimum: 10 }
end
title이라는 속성이 presence: true => 존재하는지 안하는지 확인
빈칸도 없는 것으로 간주합니다.
그리고, body는 존재하는지를 확인하고 length를 통해서 최소한 10글자 이상이되도록 validate를 합니다.
에러메세지
<div>
<%= form.label :title %><br>
<%= form.text_field :title %>
<% @article.errors.full_messages_for(:title).each do |message| %>
<div><%= message %></div>
<% end %>
</div>
<div>
<%= form.label :body %><br>
<%= form.text_area :body %><br>
<% @article.errors.full_messages_for(:body).each do |message| %>
<div><%= message %></div>
<% end %>
</div>
위의 검증과정에서 만족하지 못하는 속성에 대해서는 따로 에러메세지를 보여주는 것이 가능합니다.
full_messages_for 메소드는 지정된 속성에 대해 사용자에게 친숙한 오류 메세지 배열을 반환합니다.
해당 속성에 오류가 없으면 배열이 비어있습니다.
'IT 공부 > Ruby On Rails' 카테고리의 다른 글
[ Ruby on Rails ] 유용한 라이브러리 사용방법 (0) | 2021.09.18 |
---|---|
[ Ruby on Rails ] Pagination 기능 (0) | 2021.09.15 |
[ Ruby on Rails ] Prefix 와 Path (0) | 2021.09.14 |
[ Ruby on Rails ] 시작하기 (2) | 2021.09.06 |
[ Ruby on Rails ] Windows 환경에서 Ruby on Rails 설치하기 (0) | 2021.09.06 |