オリジナルアプリ開発#5 ヘッダーメニューをアイコン化したりページネーション作ったり
開発記録溜め過ぎてすみません…色々やってます!
こんにちは、はくたむです。
ちょっと体調崩してレッスン先延ばしになったりなんだりしていましたが、元気にアプリ制作に励んでおります。
進捗記録をどんな感じで公開して行こうかまだ手探りで、開発進めるのが楽しくて気づいたらめっちゃ溜まってました。
15,000文字くらい…。笑
何回かに分けて投稿しますので、よろしければお付き合いください。
プルリクエストの単位について
レッスン時に先生と確認したのですが、プルリクエストの単位はなるべく小さくするとレビューしてもらう時に抜け漏れが少なくなるかつレスポンスが早くなる、高速でmasterにマージできるよう進めて行きましょう、とのことでした。
と言うわけでなるべく小さく作ることを心がけて作業を進めることとします!
ヘッダーメニューをアイコンにする
前回ログイン前後でヘッダーメニューを切り替えるようにましたが、さらに追加してログイン後の画面で新規投稿ページへのリンクとユーザー編集ページへのリンクをアイコンにして追加してみようと思います。
作業ブランチadd_header_menuiconを作成
今度は間違えないように!笑
masterからブランチを作成します。
railsにFontAwesomeを導入する
簡単みたいです!
下記を参考に導入します。
Gemfile
に下記を記述してbundle install
します。
$ gem 'font-awesome-rails'
app/assets/stylesheets/application.css
に下記を記述して読み込ませます。
前回の指摘を活かして *= require_tree .より上に記述するよ。
*= require font-awesome
これで使う準備はOK!
記述したあとはサーバーを再起動させないとエラーになりましたので注意。
あとはFontAwesomeのページから使いたいアイコンを選ぶだけ。
headerのドロップダウン部分はこんな感じになりました。
<div class="dropdown"> <!-- 切替ボタンの設定 --> <div class="nav-link" id="dropdownMenuButton button_group" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <%= fa_icon 'cog 2x' %> </div> <!-- ドロップメニューの設定 --> <div class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenuButton"> <%= link_to 'マイページ', '#', class: 'nav-link dropdown-item' %> <%= link_to 'アカウント設定', edit_user_registration_path, class: 'nav-link dropdown-item' %> <div class="dropdown-divider"></div> <%= link_to 'ログアウト', destroy_user_session_path, method: :delete, class: 'nav-link dropdown-item' %> </div><!-- /.dropdown-menu --> </div><!-- /.dropdown -->
実はここでレスポンシブ対応が邪魔になっているのを感じてるのですが(わざわざしなくてもアイコンだけなので問題なさそう)この辺りはデザインをやるときに考えることとして先に進みます。
高速でマスターにマージを意識して、一旦ここまででプルリクを出します。
アカウント設定ページの編集
さて、レビューを待っている間にアカウント設定(ユーザー情報変更ページ)の編集をしようと思います。
masterブランチからedit_userinfomation_pageブランチを作成します。
特筆すべきこともなく、ログインや新規登録フォームを流用しながらapp/views/devise/registrations/new.html.erb
を修正して終わりです。
このフォーム周りってリファクタリングできるのかなぁ…なんてことを思い始めました。
あとはユーザー名変更のためapp/controllers/application_controller.rb
のStrong Parametersも変更して許可しておきましょう。
devise_parameter_sanitizer.permit(:account_update, keys: [:name] )
プルリクエスト作成&LGTM
今回は両方変更点も少なく一発OKだったのでそれぞれmasterにマージしてローカルとも同期させます。
Wordsテーブル作成
そろそろメインコンテンツの作り込みを始めよう〜!ということでまずは土台となるモデルとコントローラを作成します。
masterブランチからadd_words_tableというブランチを作成しました。
$ rails g model Word user_id:integer word:string kana:string content:text content_replace:text
事前に考えておいたテーブルの内容をざざっと書き込みモデルを作成、db:migrate
してDBに反映させます。
次にコントローラーを作成。
とりあえずindexだけにしたけどよく考えたら全部のアクション使うのでもう少し作っておいても良かったかも。
$ rails g controller words index
ちゃんとwords/indexが表示されたので、後ほどこのページをログイン後の画面にしたいと思います。
ルーティングの設定
その前にconfig/routes.rb
を編集してルーティングの設定をしておきます。
このコントローラーは全てのアクションを使用するので、リソースベースでルーティングを作成します。
resources :words
リソースベースで作成するとpath
が作成されるので便利ですね!
pathがわからなくなったらいつでもターミナルでrails routes
すれば確認できます。よく使ってます。笑
ログイン後の画面を変更する
先ほど作ったwords/indexをログイン後表示させるページに指定したいです。
とはいえdeviseのコントローラーはいじれないし…とりあえず下記を参考にしてdeviseのGitHubを眺めてみました。
app/controllers/application_controller.rb
にオーバーライドさせるメソッドを作成すればいいみたいなので書き足していきます。
このとき↑で作成したpathが役に立ちます。
def after_sign_in_path_for(resource) words_path #ログイン後のページ end
ヘッダーにリンク作成し忘れていたアカウント設定ページのリンクを追記して、一旦ここまでをプッシュしてプルリクエストを出しました。
メイン画面のデザイン作っていくことにしました
さて作業を続けますが、今回はmasterから切るとモデルやコントローラーがなくなってしまうのでadd_words_tableから新しくedit_words_indexを作成して作っていきます。
とりあえずここまで編集したのですが、ページネーションを作るためにダミーデータを作って表示やらなんやらさせてみようと思いました。
rails c
で下記のコマンドを実行して100個ダミーデータを作成します。
100.times do |i| Word.create(user_id: 1, word: "test#{i}") end
ダミーデータをindexに表示させてみる
先ほど作ったデザインの登録語を表示させる部分にダミーデータを反映させてみます。
app/controllers/words_controller.rb
でログインユーザーを取得。
class WordsController < ApplicationController def index @user = current_user end end
表示エリアをで繰り返し表示。
カラム落ちの原因を探るのにめっちゃ時間がかかってしまいました。
col-md-4
で指定したdiv
はみっちり3つ並んでしまうので、もう一個div
で囲んでその内側にpaddingで余白をつけてあげたらうまくいきました!
<div class="container mt-5"> <div class="row justify-content-around"> <!-- 登録内容繰り返し表示 --> <% @user.words.each do |word| %> <div class="p-2 col-lg-4"> <div class="word_box"> <%= word.word %> </div> </div> <% end %> </div> </div>
kaminariでページネーションの表示
登録語一覧をindexページにうまく表示できたのでページネーションをつけてみます。
下記を参考に24件ずつ表示するようにしてみました。
まずapp/controllers/words_controller.rb
でログインユーザーの登録語を取得する記述を追加。
class WordsController < ApplicationController def index @user = current_user @words = @user.words.page(params[:page]).per(24) end end
ページネーションを表示させるところに
<%= paginate @words %>
と書くだけ!
簡単でした…。
と思ったらうまくページネーションできてなくて、何事かと思ったんですが単に繰り返し表示のところで使った変数を@user.words
→@words
に変えればOKでした。
見た目の変更がBootstrapでできるとの情報を事前に得ていたのですが、調べてみたらこちらも超簡単。
下記のコマンドを入れるだけでした。
$ rails g kaminari:views bootstrap4
indexページが出来上がりました!
ここまででプルリクエストを作成しました。
単語新規登録フォームの作成
まだレビューが返ってこないので同じブランチからcreate_words_newpageというブランチを切って作業を進めます。
単語を新規登録するためのページを作っていきます。
フォームから投稿してデータベースに反映されたらOKを目標にします。
app/views/words/new.html.erb
という新規ファイルを作成し、フォームを作っていきます。
<%= form_for(@words) do |f| %> <div class="form-group"> <%= f.label :登録語 %><br /> <%= f.text_field :word, autofocus: true, class: 'form-control', placeholder: '登録語' %> </div> <div class="form-group"> <%= f.label :よみがな %><br /> <%= f.text_field :kana, autofocus: true, class: 'form-control', placeholder: 'よみがな' %> </div> <div class="form-group"> <%= f.label :メモ %><br /> <%= f.text_area :content, autofocus: true, class: 'form-control', placeholder: 'メモ', rows: 8 %> </div> <div class="actions"> <%= f.submit '新規登録', class: 'btn btn-primary badge-pill pr-4 pl-4' %> </div> <% end %>
このページを表示させるためのnew
アクションと投稿を保存するためのcreate
アクションを作りました。
作ってて気づいたのが、
やたら @user = current_user が出てくる
ということ。
Railsの考え方の一つDRYの法則に則って何回も書かずにするにはどうしたら?と色々調べていたら下記の記事を発見しました。
これで@user = current_user
をメソッド化してself.メソッド名
で呼び出してあげればいいみたいです。
というわけでコントローラは下記のようになりました。
class WordsController < ApplicationController def user @user = current_user end def index @words = self.user.words.page(params[:page]).per(24) end def new @words = self.user.words.new end def create @words = self.user.words.new(words_params) if @words.save redirect_to words_path, notice: '単語を登録しました!' else render 'new' end end private def words_params params.require(:word).permit(:word, :kana, :content) end end
あとはモデルapp/models/word.rb
にバリデーションを追加しました。
validates :word, presence: true validates :kana, presence: true validates :content, presence: true
新規登録もちゃんとできたので、ここで作業を終わりにします。
プルリクエスト作成〜!
ちなみに、一覧表示が登録古い順になってしまっていたのであとで直そうと思いました。
プルリクエストがおかしい?
ここまで連続して(masterにマージする前に)作業ブランチからブランチを切って作業を進めていたのですが、なぜかプルリクエストを作成するたびに前のプルリクエストが重複して登録されてたんですね。
原因は調べたけどよくわかりません…。
とりあえず修正点はCSSファイルの行末に空行がなかっただけ(ここでファイルが終わるよ、という目印のためファイルの最後に空行を挿入するのだそう)なので一旦全てmasterにマージして作業を進めてくださいとのことだったので進めます。
この件については次回のレッスン時に詳しく聞こうと思います。