Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What is going on with this article?
@lumbermill

Rails5.2で色々やってみる

宮崎勉強会 Advent Calendar 15日目の記事です。勉強会の中では年上の方なので、「枯れた」技術の良さを再確認するという主旨で、私の好きなRubyとRails、そのオススメのgemを幾つか紹介します。(本当はRails6の新機能を紹介する記事を書くつもりでいたんですが、環境構築で手こずって路線変更しています。6を使いたいけど、まだ導入のハードルが高かった…)

今回使用するRailsのバージョンは5.2.4です。vagrant上に構築したUbuntuでコマンドを実行しています。


$ rails -v
Rails 5.2.4

まずは、新しいプロジェクトを作成します。今回は wiki という名前にしました。生成されたプロジェクトのディレクトリに入って、データベースの初期化とサーバの立ち上げもします。PostgreSQLを指定しているのは、このあとherokuというプラットフォームに載せてみようとしてるからです。

rails new wiki --database=postgresql
cd wiki/
rails db:create
rails s -b 0.0.0.0

ブラウザで http://localhost:3000 にアクセスすると以下のような画面が表示されます(vagrantで仮想ネットワークを使っている場合はlocalhostの部分が192.168.33.10などのIPになります)。

Screen Shot 2019-12-12 at 19.22.57.png

続けてこのアプリ上で管理したいテーブルの定義をします。 page という名前のモデルに
title,body,published という3つのフィールドを定義しました。

rails g scaffold page title body published:boolean
rails db:migrate

ホストのルート(URLのホスト名以下に何も書かない状態)からアクセスできるように、rootを定義しておきます(先程のRailsの画面が見えなくなる代わりに新しく作ったモデルの一覧ページが表示されるようになります)。

config/routes.rb
  root to: 'pages#index'

このモデルを使って色んなgemの紹介をしていこうと思います。

markdownを使ってみる(redcarpet)

ここ(qiita)でも使っているMarkdown記法のテキストをhtmlにパースしてくれるのが redcarpet です。Gemfileに以下のバージョンを登録しました(Gemfileを更新したらbundleを実行してください、これ以降も同様です)。

Gemfile
gem 'redcarpet', '~> 3.5'

直接Markdownとは関係ないですが、複数行のテキスト入力をするために、bodyフィールドの編集エリアを text_field から text_area に変更します。

app/views/pages/_form.html.erb
<div class="field">
  <%= form.label :body %>
  <%= form.text_area :body %>
</div>

Redcarpetのパーザを使うためのヘルパメソッドを定義します。

app/helpers/pages_helper.rb
  def markdown(text)
    unless @renderer
      @renderer = Redcarpet::Markdown.new(Redcarpet::Render::HTML, autolink: true, tables: true)
    end
    @renderer.render(text).html_safe
  end

このメソッドでbodyの出力を囲うと、Markdownで保存されたテキストがHTMLとして整形されて出力されます。

app/views/pages/show.html.erb
<p>
  <strong>Body:</strong>
  <%= markdown(@page.body) %>
</p>

Screen Shot 2019-12-12 at 20.14.26.png

変更履歴を管理してみる(paper_trail)

paper_trailは、モデルの変更履歴(生成,更新,削除)を記録してくれます。papertrail(アンダースコアなし)という似たgemが存在するので注意してください。

Gemfile
gem 'paper_trail', '~> 10.3', '>= 10.3.1'

バージョン履歴を保存するテーブルを作ったりなどするために、以下のコマンドを実行します。


rails generate paper_trail:install
rails db:migrate

バージョン管理を行いたいモデルにhas_paper_trailと記載します。

app/models/page.rb
class Page < ApplicationRecord
  has_paper_trail
end

これだけで、モデルの各操作に対する履歴が保存されるようになります。例えば、最初に「1」という内容で作成されたpageモデルが、続けて「2」「3」と2回更新された場合、以下のように3つのバージョン履歴が残っていて、それぞれの時点で保存されていた値を参照することが可能です。

irb> p = Page.last
irb> p.body
=> "3"
irb> p.versions[2].reify.body
=> "2"
irb> p.versions[1].reify.body
=> "1"
irb> p.versions[0].reify
=> nil

IDをベースに記録されているため、モデルが削除された場合でも、同一IDのモデルを新しく作ってから、versionsを参照すると過去の状態を参照することができます。以下の例では一度削除したモデルを削除直前の状態に戻しています。

irb> p = Page.new(id:3)
irb> p = p.versions.last.reify
irb> p.save
=> true

devise などのgemと組み合わせると「誰が操作したか」という記録も合わせて保管できます。

画像をアップロードしてみる(active_storage)

Rails5.2で導入された新しい機能です。追加のgemは必要なく、以下のコマンドで有効化できます。

rails active_storage:install
rails db:migrate

今回は、pageモデルに複数の画像(images)を追加出来るようにしてみました。

app/models/page.rb
class Page < ApplicationRecord
  has_many_attached :images

ファイルをアップロードするためのフィールドを追加します。multiple: trueを忘れずに。

app/views/pages/_form.html.erb
<div class="field">
  <%= form.label :images %>
  <%= form.file_field :images, multiple: true %>
</div>

コントローラでパラメタを受け取れるようにします。

app/controllers/pages_controller.rb
def page_params
  params.require(:page).permit(:title, :body, :published, images:[])
end

アップロードされたファイルを表示する部分です。

app/views/pages/show.html.erb
<% if @page.images.attached? %>
  <% @page.images.each do |i| %>
    <%= image_tag i %>
  <% end %>
<% end %>

最終的にはAWSのS3などオブジェクトストレージに繋いで使うことを想定されているようですが、ひとまずこれだけでローカルディスクに画像などのアップロードされたファイルが貯められるようになります。

レスポンシブにしてみる(bootstrap)

Bootstrapはレスポンシブ対応のウェブサイトを構築するのに便利なライブラリです。色んなインストール方法がありますが、gemを入れてみます。

Gemfile
gem 'bootstrap', '~> 4.4.1'
gem 'jquery-rails'

bootstrap-rubygemのREADMEに従って幾つか設定の調整が必要です。例えば、Rails5.2では jquery-rails も一緒にインストールが必要です。

application.cssの代わりにapplication.scssを使用します。コピーする場合、*= requireが使えないので注意してください。

app/assets/stylesheets/application.scss
@import "bootstrap";

jsのインストールも必要です。

app/assets/javascripts/application.js
//= require jquery3
//= require popper
//= require bootstrap-sprockets

これでbootstrapが使える状態になりますが、(昔のgemにはあった気がする)自動的にスタイルを適用するgeneratorなどは見当たらないので、地道にクラスをあてて行きましょう(多分、要調査)。

アイコンを使ってみる(font-awesome-sass)

前述のBootstrap3.xまではglyphiconsというアイコンセットが一緒に使えていたのですが、4になってからどうも使い方がややこしくなっている感じです。Font Awesomeという別のセットをインストールします。

Gemfile
gem 'font-awesome-sass', '~> 5.12.0'

類似のgemにfont-awesome-railsというものがあって、こちらの方がダウンロード数が多いのですが、更新が止まっているようで最近はこちらが主になっているのかな?という感じでした。

任意のscss内にインポートします。

app/assets/stylesheets/pages.scss
@import "font-awesome-sprockets";
@import "font-awesome";

iconというヘルパ関数を使って、以下のようにアイコンを使用することができます。普通にhtml(<i class="fas fa-flag"></i>)を書いてもOKです。

<%= link_to icon('fas', 'flag')+' New Page', new_page_path %>

Screen Shot 2020-04-26 at 11.46.44.png

ユーザ管理してみる(devise)

Deviseというgemを使います。

rails g devise:install
rails g devise user

インターネットに公開してみる(heroku)

ここまで作ったアプリをherokuに乗せてみましょう(アカウントの作成とherokuコマンドのインストールは省略しています)。一番シンプルには、以下のコマンドを順番に実行するだけです。

heroku login
heroku create
git push heroku master
heroku run rake db:migrate

createの際に名前を指定しないと、ランダムな単語の組み合わせが割り当てられます。今回は以下のURLでアプリケーションが起動されました。

※ active_recordの保存先をlocalに指定しているため、データが永続化されないherokuのサーバが再起動される度に画像が消えてしまいます

まとめ

思いつくままに幾つかの機能(gem)を紹介してみました。詳しい使い方はそれぞれの公式ドキュメントを参照してみてください。Railsの真価は、「こういうときはこのgemを使ったらいいや」というストックが個人の中に溜まってきてから発揮されると感じています。デフォルトのCRUDはページ遷移を基本とした古風なインターフェースですが、これだけでも仕組み化の手助けになる場面は多いかなと思います。

参考リンク

0
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
0
Help us understand the problem. What is going on with this article?