#はじめに
プログラミングを勉強し始めて早一年、Rails以外にもFlaskやらDjangoやVue-cliなどのWebフレームワークをつついたりしてきました。
しかし、僕は気づいてしまいました。あれ?僕、何か作れるの?
このようなこともあり、今まで勉強したことを整理することもかねて簡単なWebアプリを制作しそのことについての記事を書こうと思いました。
見ていただけると今後の勉強の励みにもなります。
分からないところやおかしいところがあった際にはコメントよろしくお願いします。
テストについてはあまり知識がないのと単純に書きたくないということもあり作成しておりませんのでご了承ください。
#制作するもの
よくある書籍管理アプリです。
(書籍名は適当です。
css関係についてはすべてmaterializeに丸投げしました。
#環境
- OS Windows10 Home
- Ruby 2.4.5
- Rails 5.2.3
- Node-js 10.15.1
#プロジェクトの作成
まずはプロジェクトを作成しましょう。
$ rails new book_app
そしてrails s
と入力し、(http://localhost:3000) を開いてウェルカムページが表示されるか確認しましょう。
#homeの作成
では早速このアプリのHomeを作っていこうと思います。
rails g controller home index about help
すると以下のようにファイルが作成されたと思います。
create app/controllers/home_controller.rb
route get 'home/index'
get 'home/about'
get 'home/help'
invoke erb
create app/views/home
create app/views/home/index.html.erb
create app/views/home/about.html.erb
create app/views/home/help.html.erb
invoke test_unit
create test/controllers/home_controller_test.rb
invoke helper
create app/helpers/home_helper.rb
invoke test_unit
invoke assets
invoke coffee
create app/assets/javascripts/home.coffee
invoke scss
create app/assets/stylesheets/home.scss
次にconfig/routes.rb
の一番上に次のように追記します。
Rails.application.routes.draw do
root to: 'home#index' #これを追加
get 'home/index'
get 'home/about'
get 'home/help'
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
これにより、localhost:3000
にアクセスしたときapp/views/home/index.html.erb
の内容が表示されます。
そしてもう一度 (http://localhost:3000) にアクセスすると以下のように表示されていると思います。
#Materializeの導入
次にcssフレームワークのmaterializeを導入していきます。
Gemfile
に次の内容を追記して下さい。
#materialize
+ gem 'materialize-sass'
+ gem 'material_icons'
+ gem 'jquery-rails'
しかしWindows環境ではこのままではExecJS::ProgramError
が発生しjavascriptが正しく読み込めないたいなので、
Gemfile
のducktape
をコメントアウトしてください。
#gem 'duktape'
そしてbundle install
としてください。
次にapp/assets/stylesheets/application.scss
に以下のように記述します。
/*
*= require_tree .
*= require material_icons
*= require_self
*/
@import 'materialize/components/color-variables';
$primary-color: color("teal", "lighten-4") !default;
@import 'materialize';
primary-colorを設定することによってmaterializeのテーマカラーをデフォルトのピンクから変更することができます。
最後にapp/assets/javascripts/application.js
に以下のように追記します。
+ //= require jquery
+ //= require materialize
#ヘッダーの作成
ではheaderを作成していきたいと思います。
(https://materializecss.com/navbar.html)
を使わせていただきます。
まず、app/views/parts
とapp/views/parts/_header.html.erb
を作成してください。
そして次のように記述してください
<nav>
<div class="nav-wrapper container">
<%= link_to image_tag("logo.png", class: "brand-logo left", size: '90x60'), root_path %>
<ul id="nav-mobile" class="right hide-on-med-and-down">
<li><%= link_to "Home", root_path %></li>
<li><%= link_to "About", home_about_path %></li>
<li><%= link_to "Help", home_help_path %></li>
</ul>
<ul id="dropdown-target" class="dropdown-content">
<li><%= link_to "Home", root_path %></li>
<li><%= link_to "About", home_about_path %></li>
<li><%= link_to "Help", home_help_path %></li>
</ul>
<a href="#" class="dropdown-trigger right hide-on-large-only" data-target="dropdown-target"><i class="material-icons">arrow_drop_down</i></a>
</div>
</nav>
<script>
$(".dropdown-trigger").dropdown();
</script>
logo.png
は(https://www.logofactoryweb.com/default_lg.asp?lg=ja#_ebcv=3kxCAMrX.liskul2so.1,3kxCAMrX.liskul2so.1) で作成させていただきました。
*logo.png
はapp/assets/images
において下さい。
最後にapp/views/layouts/application.html.erb
に以下のように追記してください。
<body>
+<%= render 'parts/header' %>
<div class="container><%= yield %></div>
</body>
そして再び (http://localhost:3000) にアクセスすると以下のようになっていると思います。
#deviseのinstall
今回はログインに使うmodelを作成するために効率よくdeviseを使用します。
deviseのinstallはこちらの記事を参考にさせていただきました。
#Ownerモデルの作成
いよいよ、modelを作成していきたいと思います。Userモデルじゃないの?と思う方もいるかもしれませんが、自分の本を登録するためのmodelなのでUserよりOwnerのほうがいいと思いこっちにしました。
まずOwnerモデルの作成をします。
rails g devise owner
次にログインやサインアップのviewを作成します。
rails g devise:views
```
```rails db:migrate```でマイグレーションを実行します。
また、materializeやbootstrapなどのcssフレームワークを使うとcheck_boxが表示されなくなることがあるのでログインページを編集します。
(```<%= f.label %>```で囲むと表示されるらしい)
> (https://railstutorial.jp/chapters/advanced_login?version=5.1#sec-remember_me_checkbox) より
```erb:app/views/devise/sessions.new.html.erb
<%= f.label :remember_me do >
<%= f.check_box :remember_me %>
<span>Remeber me</span>
<% end %>
```
これで、OKです。
(http://localhost:3000/owners/sign_in) にアクセスしてみてください。ログイン画面が表示されているはずです。
#サイドバーのみたいなものの作成
クリックしたら出てくるこういうやつをつくっていきます(サイドナビゲーションだからsidenavなのかな
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281205/7bacfb2d-fc0d-94b2-9dda-5001f6e4c25f.png" width=50%>
>https://materializecss.com/sidenav.html を参考にしました。
```erb:app/views/parts/_sidenav.html.erb
<% if owner_signed_in? %>
<ul id="slide-out" class="sidenav">
<li><%= link_to 'アカウントの編集', edit_owner_registration_path %></li>
<li><%= link_to 'ログアウト', destroy_owner_session_path, method: :delete %></li>
<li><div class="divider"></div></li>
<li><%= link_to "アカウント削除", registration_path(current_owner), data: { confirm: "本当によろしいですか?" }, method: :delete, class: "red-text text-darken-2" %></li>
<li><div class="divider"></div></li>
</ul>
<a href="#" data-target="slide-out" class="sidenav-trigger"><i class="material-icons large-size menu position">menu</i></a>
<% end %>
<script>
$('.sidenav').sidenav();
</script>
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281205/b2ac6aa1-8aaf-9830-00e3-a4f5274af014.png" width=70%>
#ログイン画面に強制リダイレクト
触って見て思うかもしれませんがログインするためにいちいち (http://localhost:3000/owners/sign_in)
に移動するのがめんどくさいのでログアウト状態でaboutとhelpのページにアクセスするとログイン画面に強制リダイレクトされるように```before_action```を登録しましょう。
```app/controllers/home_controller.rb```に以下を追記します。
```ruby:app/controllers/home_controller.rb
class HomeController < ApplicationController
before_action :redirect_login, except: [:about, :help]
# 中略
def redirect_login
unless owner_signed_in?
redirect_to new_owner_session_path
end
end
end
```
これによりログアウトした後、ログイン画面にリダイレクトされていると思います。
#flashメッセージの表示
今回はこれで最後です。
やっぱり、ログイン機能をつけたのならflashメッセージはほしくなりますよねぇ。
ということでちゃちゃっと作っちゃいましょう。
>https://materializecss.com/toasts.html を参考にさせていただきました。
まず、```app/views/parts/_flash.html.erb```を作成し、
```app/views/layouts/application.html.erb```を以下のように追記します。
```erb:app/views/layouts/application.html.erb
.........
<%= render 'parts/sidenav' %>
+<%= render 'parts/flash' %>
<div class="container">
..........
```
そして```app/views/parts/_flash.html.erb```を以下のように編集します。
```erb:app/views/parts/_flash.html.erb
<% unless flash.empty? %>
<script>
<% flash.each do |key, message| %>
M.toast({html: '<%= message %>'})
<% end %>
</script>
<% end %>
```
これでログインしたとき以下のように右上にflashメッセージが表示されているはずです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281205/4003924c-2850-e0c1-fc26-193f666e5d25.png" width=70%>
---
今回はこれで終わりです。お疲れ様でした。次回はログイン画面とflashの見た目の編集と日本語化そして書籍の登録処理まで書こうと思います。貸し出し機能も書きたいので全部で4章ぐらい続きそうです....
最近はレポートがたまり消化が追いついていないので次回の更新はかなり遅れるかもしれません。
では。
---