Stimulus
, Bootstrap
, jQuery
, Popper
, Font-awesome
, SweetAlert2
, Toastr
-
레일스 젬 6 버전을 설치한다.
$ gem install rails --pre # pre-release 버전을 설치할 때 $ gem install rails -v 6.0.0.rc1 # 특정 버전을 설치할 때
-
레일스 프로젝트 blog 를 생성한다.
$ rails new blog --webpack=stimulus # 디폴트 데이터베이스 sqlite3를 사용할 때 $ rails new blog --webpack=stimulus -d postgresql # postgresql을 사용할 때 $ rails new blog --webpack=stimulus -d mysql # mysql을 사용할 때
-
프로젝트 폴더로 이동
$ cd blog
-
데이터베이스를 생성한다.
$ bin/rails db:create
-
tmux를 실행한 후 터미널 위도우를 두개로 분할하여 아래의 명령을 각각 실행한다.
$ tmux new -s blog_session $ bin/rails server # 로컬 웹서버를 시작 $ bin/webpack-dev-server # 리소스 변경시 자동으로 브라우저를 갱신한다.
-
홈 페이지 생성하기
-
home 컨트롤러 index 액션 작성하기
$ bin/rails g controller home index
-
루트 라우트 지정하기
root to: 'home#index'
-
-
패키지 추가
$ yarn add bootstrap jquery popper.js
-
config/webpack/environment.js
const { environment } = require('@rails/webpacker') const webpack = require("webpack") environment.plugins.append("Provide", new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', Popper: ['popper.js', 'default'] })) module.exports = environment
-
app/javascript/stylesheets/application.scss
@import "~bootstrap/scss/bootstrap";
-
app/javascript/application.js
import 'bootstrap' import '../stylesheets/application' document.addEventListener('turbolinks:load', () => { $('[data-toggle="tooltip"]').tooltip() $('[data-toggle="popover"]').popover() })
-
애플리케이션 레이아웃 파일의 body 태그 시작부분에 navbar 추가하고
<%= yield %>
를container
클래스로 감싸 준다.<body> <!-- 여기에 navbar 삽입 --> <div class='container'> <%= yield %> </div> </body>
아래의 bootstrap navbar 코드를 붙여넣기 한다.
<nav class="navbar fixed-top navbar-expand-lg navbar-dark bg-dark"> <a class="navbar-brand" href="#">Navbar</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarSupportedContent"> <ul class="navbar-nav mr-auto"> <li class="nav-item active"> <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a> </li> <li class="nav-item"> <a class="nav-link" href="#">Link</a> </li> <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> Dropdown </a> <div class="dropdown-menu" aria-labelledby="navbarDropdown"> <a class="dropdown-item" href="#">Action</a> <a class="dropdown-item" href="#">Another action</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="#">Something else here</a> </div> </li> <li class="nav-item"> <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a> </li> </ul> <form class="form-inline my-2 my-lg-0"> <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search"> <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button> </form> </div> </nav>
navbar 에
fixed-top
클래스를 추가하면 body의 상단 부분이 navbar에 가려 안보이게 된다. 이를 해결하기 위해서 body 태그의padding-top
값을6rem
으로 설정해 준다. app/javascript/stylesheets 폴더에 styles.scss 파일을 생성하기 아래의 내용을 붙여넣기 한다.body { padding-top: 6rem; }
app/javascript/stylesheets/application.scss 파일을 열고 방금 작성한 styles.scss 파일을 import 한다.
@import "~bootstrap/scss/bootstrap"; @import "./styles.scss";
-
패키지 추가
$ yarn add @fortawesome/fontawesome-free-webfonts
-
app/javascript/stylesheets/application.scss
$fa-font-path: '~@fortawesome/fontawesome-free-webfonts/webfonts'; @import '~@fortawesome/fontawesome-free-webfonts/scss/fontawesome'; @import '~@fortawesome/fontawesome-free-webfonts/scss/fa-regular'; @import '~@fortawesome/fontawesome-free-webfonts/scss/fa-solid'; @import '~@fortawesome/fontawesome-free-webfonts/scss/fa-brands';
-
무료로 사용할 수 있는 아이콘 리스트 : https://fontawesome.com/icons?d=gallery&m=free
<table class="table table-bordered table-sm"> <thead class='thead-dark'> <tr> <th>Style</th> <th>Icon Font</th> <th>Class</th> </tr> </thead> <tbody> <tr> <td>Solid</td> <td><i class="fas fa-address-book"></i></td> <td>fas fa-adress-book</td> </tr> <tr> <td>Regular</td> <td><i class="far fa-address-book"></i></td> <td>far fa-address-book</td> </tr> <tr> <td>Brands</td> <td><i class="fab fa-fort-awesome"></i></td> <td>fab fa-fort-awesome</td> </tr> <tr> <td>Solid</td> <td><i class="fas fa-ambulance"></i></td> <td>fas fa-ambulance</td> </tr> <tr> <td>Regular</td> <td><i class="far fa-gem"></i></td> <td>far fa-gem</td> </tr> <tr> <td>Brands</td> <td><i class="fab fa-apple"></i></td> <td>fab fa-apple</td> </tr> <tr> <td>Solid</td> <td><i class="fas fa-arrows-alt"></i></td> <td>fas fa-arrows-alt</td> </tr> <tr> <td>Regular</td> <td><i class="far fa-trash-alt"></i></td> <td>far fa-trash-alt</td> </tr> <tr> <td>Brands</td> <td><i class="fab fa-chrome"></i></td> <td>fab fa-chrome</td> </tr> </tbody> </table>
-
Post 리소스를 scaffolding 한다.
$ bin/rails g scaffold Post title content:text $ bin/rails db:migrate
-
패키지 추가
$ yarn add sweetalert2
-
app/javascript/controller/confirm_controller.js
import { Controller } from 'stimulus' import Swal from 'sweetalert2' export default class extends Controller { dialog(event) { event.preventDefault(); let originLink = event.target.href let target_id_attr = event.target.closest('tr').id Swal.fire({ title: 'Are you sure?', text: "You won't be able to revert this!", type: 'warning', showCancelButton: true, confirmButtonColor: '#3085d6', cancelButtonColor: '#d33', confirmButtonText: 'Yes, delete it!' }).then((result) => { if (result.value) { let promise = $.ajax({ type: 'DELETE', url: originLink + '.json' }) promise.fail(cancelFunc) promise.done(confirmFunc) function confirmFunc(){ $(`#${target_id_attr}`).slideUp(1000) Swal.fire("Successfully deleted.") } function cancelFunc(){ Swal.fire("Error occurred.") } } }) } }
-
app/views/posts/index.html.erb
<tr id='post-<%= post.id %>'> ... <td data-controller='confirm'> <%= link_to 'Destroy', post, data: { action: "click->confirm#dialog" } %> </td> </tr>
-
app/views/posts/_form.html.erb 파일을 열고 아래와 같이 bootstrap 용 클래스를 적용한다.
<%= form_with(model: post, local: true) do |form| %> <% if post.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(post.errors.count, "error") %> prohibited this post from being saved:</h2> <ul> <% post.errors.full_messages.each do |message| %> <li><%= message %></li> <% end %> </ul> </div> <% end %> <div class="field"> <%= form.label :title %> <%= form.text_field :title, class: 'form-control' %> </div> <div class="field"> <%= form.label :content %> <%= form.text_area :content, class: 'form-control' %> </div> <div class="actions"> <%= form.submit class: 'btn bnt-primary' %> </div> <% end %>
16, 21, 25 라인을 위와 같이 업데이트한다.
-
app/views/posts/index.html.erb 파일을 열고 table 태그(5행)와 하단(31행)의 "New Post" 링크에 클래스를 추가한다.
<table class="table table-bordered"> ···· <%= link_to 'New Post', new_post_path, class: 'btn btn-primary' %>
-
패키지 추가
$ yarn add toastr
-
전용 컨트롤러 생성하기
app/javascript/controller/flash_controller.js
import { Controller } from 'stimulus'; import toastr from 'toastr'; export default class extends Controller { static targets = [] connect(){ let messages = this.data.get("messages") if(messages) { console.log(messages) toastr.success(messages) } } }
-
스타일시트 추가하기
app/javascript/stylesheets/applictation.scss
@import "~toastr/toastr.scss";
-
HTML 코드작성
app/views/layouts/application.html.erb 레이아웃 파일의 body 태그 내의 최상단에 아래의 코드를 붙여 넣는다.
<div data-controller='flash' data-flash-messages='<%= flash[:notice] || notice %>'></div>