게시판 레이아웃 작성하기

게시판의 형태를 세가지로 분류해 보자.

형태 설명
일반형(bulletin) 일반적인 게시판의 형태. 디폴트 형태
블로그형(blog) 블로그처럼 게시물의 내용이 일렬로 보이도록 하는 형태
갤러리형(gallery) 이미지 갤러리처럼 한 줄에 여러개의 썸네일 이미지가 보이도록 하는 형태

Bulletin 모델에 post_type 속성 추가하기

게시판을 새로 추가할 때, 레이아웃를 지정하기 위해서 post_type이라는 속성을 추가하기로 한다. 이 속성은 string 속성을 가지는 것으로 한다. 이를 위해서 Bulletin 모델에 속성을 추가하는 마이그레이션 파일을 생성한다.

$ bin/rails g migration add_post_type_to_bulletins post_type
Running via Spring preloader in process 21023
      invoke  active_record
      create    db/migrate/20161216120650_add_post_type_to_bulletins.rb

그리고 db:migrate 작업을 한다.

$ bin/rake db:migrate
Running via Spring preloader in process 21600
== 20161216120650 AddPostTypeToBulletins: migrating ===========================
-- add_column(:bulletins, :post_type, :string)
   -> 0.0469s
== 20161216120650 AddPostTypeToBulletins: migrated (0.0469s) ==================

Bulletin 모델에서 이 속성을 열거형(enum)으로 선언하고 :bulletin, :blog, :gallery 심볼을 할당한다. 이를 위해서 as_enum이라는 젬을 설치한다. Gemfile에 추가하고 번들 인스톨하고 로컬 서버를 재시동한다.

Bulletin 모델에서 아래와 같이 post_type 속성을 선언한다.

class Bulletin < ApplicationRecord
  has_many :posts, dependent: :destroy
  as_enum :post_type, bulletin: 0, blog: 1, gallery: 2
end

이제 post_type_cd 속성을 integer 데이터형으로 추가한다.

$ rails g migration post_type_cd_to_bulletins post_type_cd:integer

방금 생성된 마이그레이션 파일을 열고 디폴트 값을 0으로 설정한다.

class AddPostTypeCdToBulletins < ActiveRecord::Migration[5.0]
  def change
    add_column :bulletins, :post_type_cd, :integer, default: 0
  end
end

참고 : ActiveRecord::Enum

$ bin/rails c
Running via Spring preloader in process 28065
Loading development environment (Rails 5.0.0.1)
>> bulletin = Bulletin.new
=> #<Bulletin id: nil, title: nil, description: nil, created_at: nil, updated_at: nil, post_type: nil, post_type_cd: 0>
>> bulletin.post_type
=> :bulletin
>> bulletin.post_type_cd
=> 0
>> bulletin.gallery!
=> "gallery"
>> bulletin.post_type
=> :gallery
>> bulletin.post_type_cd
=> 2
>> bulletin.blog!
=> "blog"
>> bulletin.post_type
=> :blog
>> bulletin.post_type_cd
=> 1
>> bulletin.gallery?
=> false
>> bulletin.blog?
=> true

Strong Parameter 추가하기

bulletins_controller.rb 파일을 열어 하단에 있는 bulletin_params 메소드에 아래와 같이 post_type_cd 속성을 추가한다.

def bulletin_params
  params.require(:bulletin).permit(:title, :description, :post_type_cd)
end

Bulletin 뷰 템플릿 파일의 변경

app/views/bulletins/_form.html.erb 파일을 열어 아래의 코드를 추가해 준다. Bulletin 형태를 게시판, 블로그, 또는 갤러리로 선택할 수 있게 해준다.

<%= simple_form_for(@bulletin) do |f| %>
  <%= f.error_notification %>

  <div class="form-inputs">
    <%= f.input :title %>
    <%= f.input :description, input_html: { rows: 5 } %>
    <%= f.input :post_type_cd, collection: enum_option_pairs(Bulletin, :post_type, true) %>
  </div>

  <div class="form-actions">
    <%= f.button :submit %>
  </div>
<% end %>

app/views/bulletins/show.html.erb 파일을 열어 아래의 코드를 추가한다. 선택한 게시판의 형태를 표시할 것이다.

<tr>
  <th>Post Type</th>
  <td><%= @bulletin.post_type.capitalize %></td>
</tr>

이상으로 Bulletin 모델에서 추가할 작업이 완료되었다.

이제는 게시판의 형태에 따라 다른 뷰를 보이도록 하기 위해서 app/views/posts/ 디렉토리에 post_types라는 하위 디렉토리를 만들고 이 디렉토리에 _bulletin.html.erb 파일과 _blog.html.erb, _gallery_html.erb 파일을 생성한다.

posts 컨트롤러의 index 액션 뷰 파일의 모든 내용을 _bulletin.html.erb 파일로 이동하고 상단의 부분을 아래와 같이 변경한다.

<h2><%= bulletin_name params[:bulletin_id] %></h2>

안내

bulletin_name 헬퍼 메소드는 잠시 후에 설명할 것이다.

그리고, index.html.erb는 아래와 같이 수정한다. render 메소드는 partial 템플릿 파일을 인수로 받아 렌더링 결과를 삽입해 준다. 루비에서는 이중 인용부호 내의 #{expression}을 표현식의 결과로 대체해 준다. 따라서 @bulletin.post_type 값이 'bulletin'일 경우 "posts/post_types/bulletin"로 평가되어 app/views/posts/post_types/ 디렉토리의 _bulletin.html.erb이라는 partial 템플릿 파일을 render 메소드가 처리하게 된다.

<%= render "posts/post_types/#{@bulletin.post_type}" %>

노트

partial 템플릿 파일에서는 부모 템플릿 파일에서 사용하는 모든 인스턴스 변수를 그대로 사용할 수 있다.

post 객체의 bulletin_id 속성값으로부터 게시판 이름을 얻기 위한 헬퍼 메소드를 작성한다. app/helpers/posts_helper.rb 파일을 열고 아래와 같이 추가한다.

module PostsHelper

  def bulletin_name(bulletin_id)
    Bulletin.find(bulletin_id).title
  end

end

_blog.html.erb 파일의 내용을 아래와 같이 작성한다. 테이블 형태로 게시물을 보여줬던 index.html.erb와 비교해보면 조금 달라졌다.

<h2><%= bulletin_name params[:bulletin_id] %></h2>

<% @posts.each do | post | %>
    <div class='post'>
      <div class='title'><%= post.title %></div>
      <div class='content'><%= simple_format post.content %></div>
      <div>
          <%= link_to 'Show', [post.bulletin, post], class:'btn btn-default' %>
          <%= link_to 'Edit', edit_bulletin_post_path(post.bulletin, post), class:'btn btn-default' %>
          <%= link_to 'Destroy', [post.bulletin, post], method: :delete, data: { confirm: 'Are you sure?' }, class:'btn btn-default' %>
      </div>
    </div>
<% end %>

<br>

<%= link_to 'New Post', new_bulletin_post_path, class: 'btn btn-default' %>

이제 posts 뷰 템플릿 파일들을 아래와 같이 수정한다.

posts#new 뷰 템플릿 파일

"New post"라는 제목 대신 글을 올리는 게시판 이름이 나오도록 했다.

<h2><%= bulletin_name params[:bulletin_id] %></h2>

<%= render 'form' %>

posts#edit 뷰 템플릿 파일

"Editing post"라는 제목 대신 글을 수정하는 게시판 이름이 나도오록 수정했다.

<h2><%= bulletin_name params[:bulletin_id] %></h2>

<%= render 'form' %>

posts#show 뷰 템플릿 파일

게시판 이름이 보이도록 수정했고 테이블 형태로 글을 보여준다.

<h2><%= bulletin_name params[:bulletin_id] %></h2>

<table class='table'>
<tr>
  <th>Title</th>
  <td><%= @post.title %></td>
</tr>
<tr>
  <th>Content</th>
  <td><%= @post.content %></td>
</tr>
<tr>
  <th>Created at</th>
  <td><%= @post.created_at %></td>
</tr>
</table>

<%= link_to 'Edit', (@bulletin.present? ? edit_bulletin_post_path(@bulletin)  : edit_post_path(@post)), class: 'btn btn-default' %>
<%= link_to 'List', (@bulletin.present? ? bulletin_posts_path(@bulletin) : posts_path), class: 'btn btn-default' %>

이제 브라우저에서 http://localhost:3000/bulletins/3/edit로 접속한 후 게시판의 종류를 블로그로 변경한 후,

CSS 클래스 post, title, contentapp/assets/stylesheets/posts.scss 파일에 작성해 준다.

.post {
  border: 1px solid $gray-light;
  border-radius: 5px;
  padding:1em;
  margin-bottom: 1em;
  .title {
    font-weight: bold;
    font-size: 1.5em;
    margin-bottom:.5em;
  }
}

그리고, app/assets/stylesheets/ 디렉토리에 있는 application.scss 파일을 열고 아래와 같이 작성한다.(@import 'posts';을 추가했음)

$light-orange: #ff8c00;
$navbar-default-color: $light-orange;
$navbar-default-bg: #312312;
$navbar-default-link-color: gray;
$navbar-default-link-active-color: $light-orange;
$navbar-default-link-hover-color: white;
$navbar-default-link-hover-bg: black;

@import "bootstrap-sprockets";
@import "bootstrap";
@import 'posts';    <<< 추가함.

body { padding-top: 60px; }

이제 브라우저에서 상단 메뉴 중 가입인사를 클릭하고 가입인사를 테스트로 몇개 새로 추가하면 아래와 같이 변경되어 보이게 된다.


Git소스 https://github.com/rorlab/rcafe2/tree/chapter_05_10

results matching ""

    No results matching ""