20210111のRailsに関する記事は14件です。

【環境構築】Ruby on Rails 5.2系の開発環境を構築【1時間以内】

内容

「プログラミングをはじめたい!」「Webエンジニアを目指したい!」という思いを持ち始めたプログラミング初学者の方が、Ruby及びそれを使ったフレームワークであるRuby on Railsに挑戦するというのは王道の学習パターンなのではないかと思います。

Ruby on Railsをはじめるにあたって最初に大きな壁として立ちはだかるのが環境構築です。私自身も約3ヶ月前に異業種からの転職でRubyエンジニアとして働きはじめたばかりなので、環境構築などの「プログラミング学習を始める以前の準備」に時間を取られた時のことは記憶に新しいです。

本記事では、一人でも多くのプログラミング初学者の方にRailsの魅力を感じて欲しいという思いから「Ruby on Rails 5.2系の 開発環境を1時間以内に手に入れる」ことを目標に、そのための手順を紹介します。

※ 本記事の姉妹記事はこちら
【環境構築】Ruby on Rails 6 開発環境を1時間以内に手に入れる
【初心者向け】Ruby on Rails チュートリアル第4版(Rails5.1)の環境構築を1時間以内で!

ゴール

Ruby on Rails5.2系の開発環境を備えたUbuntuの仮想環境をmacOS上に構築する(目標1時間以内)。

前提環境

macOSCatalina バージョン 10.15.7

※ Windowsの方はゴメンナサイ。また、macOSの方でもバージョンの差異で多少の違いが発生する可能性はあります。

Virtual Box 6.1.16

※ インストール手順は後述

Vagrant 2.2.14

※ インストール手順は後述

想定する読者

・macOSユーザーの方
・macOSのターミナルを使った経験があり、基本的なLinuxコマンド(cd, mkdir, lsなど)の意味を知っている方
・ProgateなどでRuby on Railsの概要を学んだことがある方
・AWS Could9などのクラウドベースの統合開発環境に限界を感じている方
・過去にRuby on Railsの環境構築に挫折した経験のある方

仮想環境とは?

使っているOS(ホストOS:本記事ではmacOSを想定)の中に、あたかも別のOS(ゲストOS:本記事ではUbuntuを使用)が入っているような環境のことを言います。

ホストOS上に開発環境を直接構築する場合、誤った設定や削除を行ってしまったことによりホストOSに悪影響を与えてしまう可能性はありますが、仮想環境上で環境構築をする場合であれば、何かミスをしてしまった時はその仮想環境ごと削除してやり直せば良く、ホストOSに悪影響を与えることはありません。

また、AWS Could9などのクラウドベースの統合開発環境よりもリソース拡張の自由度が高く、CPUの性能限界やメモリ不足に悩まされることは(少なくともRailsでWebアプリケーションを開発するだけであれば)ほとんどないと言っていいと思います。

Virtual Box

仮想環境を構築するための「仮想化ソフト」として、まずはVirtualBoxをインストールします。

下記のダウンロードページから、(本記事ではmacOSを想定しているので)「OS X hosts」のリンクをクリックしてインストーラをダウンロードしてください。

ダウンロードしたインストーラを起動すれば、インストール手順がわかりやすく書いてあるので、それに従えばVirtual Boxのインストールは終了となります。

(※ 2021年1月11日現在の最新版は6.1.16なので、ここからはそのバージョンでの動作を前提としております)

Virtual Box ダウンロードページ

Vagrant

次に、仮想化ソフトを管理するツールであるVagrantをインストールします。
下記ダウンロードページにアクセスし、上記のVirtualBoxと同様に、インストーラのダウンロード、インストーラ起動、インストールという手順を踏めばほとんど迷うことなく完了すると思います。

仮想化ソフトである「VirtualBox」を操作するためのツールが「Vagrant」である、という認識を持っていただければとりあえず最低限の知識としてはOKです。

(※ 2021年1月11日現在の最新版は2.2.14なので、ここからはそのバージョンでの動作を前提としております)

Vagrant ダウンロードページ

環境構築手順

Virtual BoxとVagrantを問題なくインストールしたら、ここからは実際に仮想環境を構築して行きたいと思います。今回は、Ubuntu(18.04)というゲストOSが入っている仮想環境を構築します。

ここからの操作はmacOSのターミナルで行います。作業に入る前にvagrantが正しくインストールされていることを確認しましょう。ターミナルを開いてvagrant -vと入力してみてください。Vagrant 2.2.14という出力が返ってくれば準備はOKです、早速はじめていきましょう!

1. vagrant-vbguestのインストール

$ vagrant plugin install vagrant-vbguest

仮想マシンでの操作を簡単にしてくれる役割がある、という理解でとりあえずはOKです。

2. 任意の場所にディレクトリを作成

$ mkdir rails5_dev
$ cd rails5_dev

3. Vagrantfile作成

$ vagrant init

上記コマンドでデフォルトのVagrantfileが作成されます。

Vagrantfile(デフォルト|一部抜粋)
# -*- mode: ruby -*-
# vi: set ft=ruby :

# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure("2") do |config|
  ~
  ~
  config.vm.box = "base"
  ~
  ~
  # config.vm.network "forwarded_port", guest: 80, host: 8080
  ~
  ~
  # config.vm.network "private_network", ip: "192.168.33.10"
  ~
  ~
end

上記のデフォルト状態のVagrantfileの中身を、下記のコードに書き換えてください。

Vagrantfile(書き換え後)
# -*- mode: ruby -*-
# vi: set ft=ruby :
# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure("2") do |config|
  GUEST_RUBY_VERSION = '2.6.6'
  GUEST_RAILS_VERSION = '5.2.4.4'
  config.vm.box = "bento/ubuntu-18.04"
  config.vm.box_check_update = false
  config.vm.network "forwarded_port", guest: 3000, host: 3000
  config.vm.network "private_network", ip: "192.168.33.10"
  config.vm.synced_folder "./", "/home/vagrant/work"
  config.ssh.forward_agent = true
  config.vm.provider "virtualbox" do |vb|
      vb.gui = false
  end
  config.vm.provision "shell", inline: <<-SHELL
      echo '### installing tools ###'
      sudo timedatectl set-timezone Asia/Tokyo
      sudo apt update -y
      sudo apt upgrade -y
      sudo apt install build-essential -y
      sudo apt install -y libssl-dev libreadline-dev zlib1g-dev
      sudo apt install -y imagemagick
  SHELL
  config.vm.provision "shell", privileged: false, inline: <<-SHELL
      echo '### installing Ruby ###'
      git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
      echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
      echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
      source ~/.bash_profile
      git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
      rbenv install #{GUEST_RUBY_VERSION}
      rbenv global #{GUEST_RUBY_VERSION}
      echo '### installing Rails ###'
      gem install rails -v #{GUEST_RAILS_VERSION}
      echo '### installing SQLITE3 ###'
      sudo apt install libsqlite3-dev
      sudo apt install sqlite3
      echo '### installing NodeJS ###'
      sudo apt install -y nodejs npm
      sudo npm install n -g
      sudo n lts
      sudo apt purge -y nodejs npm
      sudo apt -y autoremove
      echo '### increasing inotify ###'
      sudo sh -c "echo fs.inotify.max_user_watches=524288 >> /etc/sysctl.conf"
      sudo sysctl -p
      echo ' -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-'
      echo 'You are now on Rails!'
      echo ' -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-'
  SHELL
end

本記事での解説は避けますが、このVagrantfileにはRailsを使えるようにするための設定が書いてあります。最初は難解に感じるかもしれませんが、ぜひ一度、読み解くことをオススメします。

もちろん私が書いたこのVagrantfileが唯一の正解では決してないので、「もっといい書き方があるよ」「こっちの方が使いやすいと思う」っていうご意見も大歓迎です!

4. 仮想環境構築

$ vagrant up

上記コマンドで仮想環境を構築します(PCのスペックにもよりますが、15〜30分ほどかかります)。

先ほどのVagrantfileに書かれた設定を1行ずつ実行していくことでRailsの開発環境が作られていっているということだけは抑えて頂けるといいかなと思います。

5. 仮想環境へSSH接続

$ vagrant ssh

上記コマンドで出来上がった仮想環境にSSH接続します。

SSH接続とは、ネットワークを経由して自身のPCから他のPC(今回は仮想環境)を安全に遠隔操作するための仕組みである、ということだけは抑えておいてください。

ここまでがmacOSのターミナルでの操作です。次の「6. Railsアプリケーション作成」と「7. ssh接続の終了」ではmacOSからssh接続をして、ゲストOSのUbuntuを操作しているということをご認識ください。

6. Railsアプリケーション作成

vagrant@vagrant:~$ cd work
vagrant@vagrant:~/work$ rails new sample-app
vagrant@vagrant:~/work$ cd sample-app
vagrant@vagrant:~/work/sample-app$ rails s -b 0.0.0.0

この状態でhttp://localhost:3000/にアクセスすると、Yay! You’re on Rails!のデフォルト画面が表示されます。

rails

立ち上げたRailsサーバーはcommand + Cで停止することができます。

7. ssh接続の終了

$ exit

上記コマンドでSSH接続を終了することができます。

8. 仮想環境のマシンをシャットダウンする

vagrant halt

上記コマンドで仮想環境上のゲストOSをシャットダウンすることができます。

再度立ち上げたい時は、vagrant upで立ち上げvagrant sshで接続します(2回目以降は数分で完了します)。

9. Railsアプリケーションの開発を進める方法

「2. 任意の場所にフォルダを作成」で作成したディレクトリ内に「6. Railsアプリケーション作成」で作成したRailsアプリと同名のファイルが作成されているはずなので、そこのコードを書き換えることで開発を進めます。

rails g controller Usersbundle install 等のコマンドはSSH接続をした状態で、作成したRailsアプリケーションのディレクトリ上で叩くことになります。

終わりに

いかがでしたでしょうか?スムーズに行けば、Yay! You’re on Rails!の表示まで1時間以内にいけるではないかなと思っております。

Rubyという言語、Railsというフレームワークは触っていると本当に面白くて飽きないものなので、この記事で環境構築をしたことをきっかけに少しでもその魅力にハマっていただければ嬉しい限りです。

本記事についての質問や改善点のご指摘等がございましたら、コメントやTwitterでのDMなどをいただければ幸いです!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Herokuにデプロイしたアプリのデータベースを確認する方法

参考記事

https://freesworder.net/heroku-dataclips/
こちらの方の記事を参考にさせていただきました。

SELECT カラム名 FROM テーブル名

を、Heroku内にあるDataclipsにて実行すると、データベースの中身を確認することができました。

実際の記入例

SELECT "name" FROM users

上記コマンドだと、指定したもののみの取得になるのですが、テーブル内に含まれているデータ全て、を一気に取得するには、

SELECT * FROM users

のようにすると、usersテーブルの中に含まれているデータをまとめて取得できます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Heroku】デプロイしたRailsアプリにAWSのS3を紐付ける

参考URL

https://qiita.com/params_bird/items/dc2a3868f4a2caf0504c

基本的に、上記URLの記事を参考にさせていただきました。

変更した部分

上記記事の後半部分、ターミナルにてコマンドを入力する箇所が、記事の通りにやってもできなかったので、そこだけ私が行った手順を記します。

$ heroku config --app デプロイしているアプリ名

https://reasonable-code.com/heroku-config/ (上記コマンドはこちらの記事から)

$ heroku config:set S3_ACCESS_KEY="ココに先ほどメモしたアクセスキーを入力" --app デプロイしているアプリ名
$ heroku config:set S3_SECRET_KEY="同様に、シークレットキーを入力" --app デプロイしているアプリ名
$ heroku config:set S3_BUCKET="バケットの名前を入力" --app デプロイしているアプリ名
$ heroku config:set S3_REGION="リージョンの名前を入力" --app デプロイしているアプリ名

最初に紹介したURLと違う部分は、【 --app デプロイしているアプリ名】です。
これを付け加えることで、無事にコマンドを実行することができて、Herokuにデプロイしているアプリから、画像を保存することができるようになりました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails入門】form_with(local: true)

Rails5.1より推奨されているform_withについて、今回はオプションの1つlocal: trueについて簡単に説明します。

local: trueとは

<%= form_with(model: @user, local: true) do |f| %>

https://railsdoc.com/page/form_with
こちらのRailsドキュメントにオプション一覧が記載されているが、ここの説明によると「リモート送信の無効(デフォルトはfalse)」とのこと。
つまり、local: trueを入力していない場合、非同期通信(Ajaxによる通信)が行われる。
local: trueを入力すれば、非同期通信をキャンセルし、HTMLとしてフォームの送信が可能になる。

Ajaxについては、以下の記事が大変わかりやすかったです。
https://pikawaka.com/word/ajax

補足などありましたら、是非コメントお願いします!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ActionView を単体で使用する(6.0以降対応)

ActionView を単体で利用する場合は、ActionView 5.2 までは次のようなコードを書いていました。

def html
  view_context.assign(staffs: [{ name: 'Alice', position: 'supervisor' }])
  view_context.render(template: 'index',
                      prefixes: 'staffs')
end

def lookup_context
  return @lookup_context if @lookup_context

  @lookup_context = ActionView::LookupContext.new('./views')
  @lookup_context.cache = false
  @lookup_context
end

def view_context
  @view_context ||= ActionView::Base.new(lookup_context)
end

p html

ActionView 6.0 からは同じコードを利用していると、次のような WARNING が発生していました。

DEPRECATION WARNING: ActionView::Base instances must implement `compiled_method_container` or use the class method `with_empty_template_cache` for constructing an ActionView::Base instance that has an empty cache. (called from html at app.rb:13)

また、2020/12にリリースされた ActionView 6.1 からは ActionView::Base.new でシンタックスエラーが発生するようになりました。

Traceback (most recent call last):
    7: from app.rb:41:in `<main>'
    6: from app.rb:6:in `execute'
    5: from app.rb:6:in `open'
    4: from app.rb:7:in `block in execute'
    3: from app.rb:12:in `html'
    2: from app.rb:27:in `view_context'
    1: from app.rb:27:in `new'
/Users/soruma/program/only_action_view_6_1_example/vendor/bundle/ruby/2.7.0/gems/actionview-6.1.1/lib/action_view/base.rb:230:in `initialize': wrong number of arguments (given 1, expected 3) (ArgumentError)

WARNING に書かれている通り、

ActionView :: Baseインスタンスは、 compiled_method_containerを実装するか、空のキャッシュを持つActionView::Baseインスタンスを構築するためにクラスメソッドwith_empty_template_cacheを使用する必要があります。

に変更しなければなりません。

Google先生に聞いても答えが出てきませんでいたが、 ActionView のテストにヒントが書かれていました。

@view = Class.new(ActionView::Base.with_empty_template_cache) do
  def view_cache_dependencies; []; end

  def combined_fragment_cache_key(key)
    [ :views, key ]
  end
end.with_view_paths(paths, @assigns)

今回、私はRails 6.1対応するにあたって次のように実装しました。

def html
  view(staffs: Staff.new.execute).render(template: 'index',
                                         prefixes: 'staffs')
end

def view(assigns)
  Class.new(
    ActionView::Base.with_empty_template_cache
  ).with_view_paths('./views', assigns)
end

今回のソースはGithubに保存しています。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

rails チュートリアル10章まとめ(自己学習用)

seeds.rbとは

初期データを生成してくれるファイルのこと。
このファイルにデータを生成するコードを書いておくだけで、アプリにデータを備えさせることができます。
簡単にテストデータを作ったりできます。

使い方

1.自分が用意したいデータをファイル内でcreateする。

db/seed.rb

通常の場合

User.create(name: "tanaka")
User.create(name: "sato")

配列の場合

users = User.create([{name: "tanaka"}, {name: "sato"}])

大量のテストデータの場合

100.times do |n|
User.create(title: "test{n}人目", content:"test!#{n}回目")
end

2.seedファイルを実行する

$ rails db:seed
おまけ
実際に存在しそうなデータを生成してくるgem(Faker)があるので一応載せておきます。

1.Gemfileに以下を追記

gem 'faker'
こちらも忘れず実行してください。

$ bundle install
2.seeds.rbを以下のように記述する。

db/seed.rb
100.times do |n|
name = Faker::Name.name
email = Faker::Internet.email
content = "test"

User.create(
name: name,
email: email,
content: content
)
end
3.seedファイルを実行する。

$ rails db:seed
※Fakerの使い方一覧は以下の表参照。

種類 役割
Faker::Name.name 名前
Faker::Internet.email メールアドレス
Faker::Address.city 都市の名前
Faker::Food.ingredient 食べ物の名前


paginationとは

Railsには豊富なページネーションメソッドがあります。今回はその中で最もシンプルかつ堅牢なwill_paginateメソッドを使ってみましょう。これを使うためには、Gemfileにwill_paginate gem とbootstrap-will_paginate gemを両方含め、Bootstrapのページネーションスタイルを使ってwill_paginateを構成する必要があります。まずは各gemをGemfileに追加してみましょう

①Gemfileにwill_paginateを追加する
②bundle install


render @**

renderはパーシャルの読み込みだけでなく、@userのような変数を与えると、railsは自動的にUserオブジェクトのコレクションを呼び出し、リストアップしその後、_userのパーシャルにデータを代入し、出力する。


beforeメソッド(controllerで使用)

before_actionメソッドを使用することで、コントローラー内の特定のアクションを行う前に、before_actionメソッドを実施できる。(デフォルトは全アクション、:onlyで特定のアクションを指定できる)
使用例:ユーザー情報の更新、削除など

書き方
before_action :logged_in_user, only: [:index, :edit, :update, :destroy]


Strong Parameters

Strong Parametersを使うことで、必須のパラメータと許可されたパラメータを指定することができます。さらに、上のようにparamsハッシュをまるごと渡すとエラーが発生するので、Railsはデフォルトでマスアサインメントの脆弱性から守られるようになりました。

この場合、paramsハッシュでは:user属性を必須とし、名前、メールアドレス、パスワード、パスワードの確認の属性をそれぞれ許可し、それ以外を許可しないようにしたいと考えています。これを行うには、次のように記述します。

params.require(:user).permit(:name, :email, :password, :password_confirmation)
このコードの戻り値は、許可された属性のみが含まれたparamsのハッシュです(:user属性がない場合はエラーになります)。

これらのパラメータを使いやすくするために、user_paramsという外部メソッドを使うのが慣習になっています。このメソッドは適切に初期化したハッシュを返し、params[:user]の代わりとして使われます。


data:{confirm: }

Railsではデータの削除時などに簡単に確認ダイアログを表示する仕組みが用意されています。
下に示すlink_to メソッドの引数に data: {confirm: 'メッセージ' } のように記述することにより、 リンクやボタンをクリックする際にブラウザに組み込まれている確認ダイアログを表示させることができます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【ポートフォリオ解説】『Share-read』 〜shareして本の知識を自分のものに〜

はじめに

プログラミングの学習のアウトプットとして、webアプリのポートフォリオを作成しました。
作成したwebアプリ名は『Share-read』です。
「shareして本の知識を自分のものにしよう」というコンセプトを掲げています。

トップ画.png

本記事では、制作背景から今後の課題まで本ポートフォリオの全てを記載します。
よかったら最後までご覧ください!

制作背景

社会人になってから、ビジネス本や自己啓発本を読むようになりました。
しかし、読んだらそれっきりになり、せっかく読んだ本の内容もあまり覚えておりませんでした。

ある時アウトプット大全という本を読み、本のアウトプットの重要性を考えさせられました。
そこで、本の内容をアウトプットするために、読書会に参加することにしました。
読んだ本をまとめて人に共有するという工程を踏むだけでも、これまでの読書と打って変わり、本の知識が頭に深く残っていました。
さらに、業務中も本の知識を活かせるようになってきました。

以前の私のように本を読んで終わってしまっている方は、少なからずいるのではないかと考えました。
読書というのは読んで終わりではなく、本の知識を自分の知識として使える状態にすることがゴールであると私は考えております。
そのような考えから本の内容をアウトプットするwebアプリ『Share-read』を開発しようと思いました。

コンセプト

『shareして本の知識を自分のものに』
本の内容をアウトプットして、知識を自分のものとして使える状態にすることを目的としています。

ターゲット

『20代〜30代前半の若手ビジネスマン』
ビジネス書を読もうとするビジネスマン、特に経験が浅い若手ビジネスマンをターゲットに設定しました。

ペルソナ

実際の開発では、ターゲット層からさらにペルソナを設定して担当者間の認識を合わせると思ったため、今回のアプリ開発でもペルソナを設定しました(ほぼ僕のプロフィールですが笑)。

年齢:26歳
職業:メーカーの研究開発部に所属
住居:都内
家族:独身
趣味:筋トレ、散歩、カラオケ

休日は筋トレや散歩をしつつ、空いた時間に読書をする。
読書に関しては、本を読むだけで、特にアウトプットもしていない。
SNSはTwitterとFacebookを使っている。
Twitterはほぼ毎日利用するが、Facebookの利用頻度は低い。
YouTubeを見ることが好きで、最近はSASUKEに出演されている方が取り組まれているチャンネルを見ている。

ポジショニング

本に関するwebアプリはいくつかありますが、マップ化することで、違いを明確化しました。
ビジネス本に特化したアウトプットの領域は既存サービスにはなく、しっかりと差別化できていることがわかりました。
image.png

webアプリの使用イメージ

  • 本の検索
    本の検索.gif

  • 本のレビュー
    本のレビュー.gif

機能

  • ユーザー関連

    • 新規登録機能 / 登録情報編集機能(画像登録可能)
    • ログイン機能 / ゲストログイン機能(登録なしでログイン可能)
    • フォロー機能(ajaxの利用)
    • 通知機能
  • 本関連

    • 本の検索機能(楽天APIの利用)
    • 本棚登録機能(ajaxの利用)
    • 楽天の購入ページへのリンク追加
  • レビュー関連

    • レビュー投稿機能/レビュー編集機能
    • レビューの下書き機能
    • お気に入り機能(ajaxの利用)
    • コメント投稿・削除機能(ajaxの利用)
    • コメント編集機能

技術・環境

フロントエンド

  • Bootstarp 4.50
  • HTML/CSS
  • JavaScript、jQuery

バックエンド

  • Ruby 2.7.2
  • Rails 6.0.3.4

開発環境

  • Docker/Docker-compose
  • MySQL 5.7

本番環境

  • AWS(VPC、EC2、RDS for MySQL、S3、ALB、 IAM、Route53)
  • MySQL 5.7
  • Nginx、puma
  • Capistrano

ER図

image.png

インフラ構成図

インフラ構成図.png

工夫した点

UI/UX

  • サイトのデザイン(配色や配置)は同じようなターゲット層と想定されるサイトを参考にしました。
  • 投稿のしやすさを意識し、レビューの投稿画面はmodalで表示しました。
  • 内容の吟味をしながらレビューできるように下書き機能をつけました。

環境・技術

  • チーム開発を意識し、Gitにpushする際は必ずプルリクを出し、Github上でマージするよう心掛けました。
  • 実際の開発を想定し、Rspecでテストコードを記載いたしました。

苦労した点

特に苦労した以下の2点を記載いたします。

楽天APIの利用

外部APIとして楽天APIを利用したのですが、テーブルへの格納等の部分で非常に苦労しました。
楽天APIのサイトやweb上の記事を参考にしながら、実装することができました。
アウトプットとしてQiitaにも記事にしました。
https://qiita.com/Hiroaki_jr/items/983b11a45e2b42c8f3dc

Dockerの使用

今回開発環境にDockerを用いましたが、必要なツールのインストールができていなかったり、データベースの不具合が起きたりと様々なエラーに苦しめられました。
エラー文の読み込んだり、調べたりしながらなぜエラーが起きてしまったのか考えながら進めました。

現アプリの課題

一通り使える状態であるため、アプリをデプロイしておりますが、以下のような点は課題と考えており、現在解決中です。

機能面

  • レスポンシブの完全対応
    レスポンシブ対応が不十分なところがあるため、実装した方が良いと考えています。

  • Twitterログイン
    ターゲットが若手のビジネスパーソンであり、Twitterの利用をしている方は非常に多いです。
    そのため、実際の利用を考えるとTwitterのログインはあるとより良いと考えています。

技術・環境面

  • circle CIによる自動デプロイの実装
    現在はCapistranoを用いたデプロイを実装しています。
    実際の開発現場においては、CircleCIが主流かと思いますので、こちらも課題であると考えています。

  • 本番環境のブラッシュアップ
    今後はACS等を用いて本番環境でもコンテナ技術を用いていく必要があると考えています。

  • リファクタリング
    現在、rubocop等のコード解析ツールを用いてリファクタリングを実施中です。

  • 結合テスト、統合テストコードの記載
    今回のポートフォリオでは、モデルの単体テストのみとなっているため、今後はRspecの学習に継続して取り組み、結合テストや統合テストも記載していく予定です。

感想

ここまで読んでいただきありがとうございました!
アプリを開発してみて思ったのは「やっぱり新しい価値を考えて、具現化していくのは楽しい!」ということでした。
実際アプリをデプロイした時は、ガッツポーズしながら、ニヤニヤしていました(at ガスト)。
とはいえ、現在のwebアプリにもまだ課題はあります。
実際のサービスにおいても常にブラッシュアップをしていくと思います。
そのため、本アプリでも現在の課題を改善し、webアプリのブラッシュアップをしていきます!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails Tutorial の拡張機能:RSSフィード機能を作ってみた

Rails Tutorialの第14章にある、拡張機能を作る件の続きです。

今回はRSSフィード機能を作ります。

要件の確認

チュートリアルでは、

ユーザーごとのマイクロポストをRSSフィードする機能を実装してください。次にステータスフィードをRSSフィードする機能も実装し、余裕があればフィードに認証スキームも追加してアクセスを制限してみてください。

と要件が書いてあります。

RSSは利用したことはありますが、どういう仕組みなのかはあまりよく分かっていません。
作った人がいるかネットで調べてみます。

feed.rss.builderという標準で搭載されている Builder 機能があるようです。

次にフィードに認証スキームですが、ログオンしていないとフォローできないと言う意味と捉えました。
実例があるのかネットで調べます。

Twitterが認証しているかネットで調べます。Twitter自体はRSSを配信しておらず、別のサイトからRSSを取得しているようです。facebookも昔はオフィシャルの機能としてRSSを提供していたが、打ち切ったとのことした。

参考:認証ありのサイトでRSSを取得するには
http://ユーザ名:パスワード@RSSフィードのURL

でできるとかなり古いネットの記事で見つけましたが、URLに記載するというのはパスワード漏洩のリスクが高そうです。

調べた結果から要件をまとめました。
1.自分自身のポストを、RSSフィードで出力する機能
2.RSSフィードを登録するアイコンとリンクをホームに追加
3.ステータスフィード、つまりフォローしている人も含むポストを、RSSフィードで出力する機能
4.RSSに認証をかけるのは難しそうなので今回はやらない

仕様を設計

要件から具体的な機能に落とし込みます。

1.自分自身のポストを、RSSフィードで出力する機能
urlのxxx/rssにアクセスすると、RSSファイルが返される。

2.RSSフィードを登録するアイコンとリンクをホームに追加
ホームにリンクを追加する。

3.ステータスフィード、つまりフォローしている人も含むポストを、RSSフィードで出力する機能
urlのxxx/rssにアクセスすると、RSSファイルが返される。

自分自身のポストをRSS出力:コントローラーの追加

トピックブランチを作ります。

ubuntu:~/environment/sample_app (master) $ git checkout -b rss

http://miner.hatenablog.com/entry/2017/07/20/142532 
を参考にします。

ルーティングを追加します。

config/routes.rb
  get :rss, to: 'rss#index', defaults: { format: :rss }

コントローラーを生成します。

ubuntu:~/environment/sample_app (rss) $ rails generate controller Rsss
      create  app/controllers/rsss_controller.rb
      create    app/views/rsss
      create    test/controllers/rsss_controller_test.rb
      create    app/helpers/rsss_helper.rb
      create      app/assets/javascripts/rsss.coffee
      create      app/assets/stylesheets/rsss.scss

コントローラーに、userのshowを参考にして、追記します。

app/controllers/rsss_controller.rb
class RsssController < ApplicationController

  layout false
  def index
    @user = User.find(params[:id])
    @microposts = @user.microposts.limit(10) 

    respond_to do |format|
      format.rss
      format.atom
    end
  end
end

ビューを作成

ビューを作成します。

app/views/rsss/index.rss.builderファイルを作成します。

app/views/rsss/index.rss.builder
cache 'feed_cache_key', expires_in: 30.minutes do
  xml.instruct! :xml, :version => "1.0"
  xml.rss :version => "2.0" do
    xml.channel do
      xml.title "Rails Tutorial sample site"
      xml.description "Rails Tutorial sample site"
      xml.link root_url

      @microposts.each do |b|
        xml.item do
          xml.title b.title
          xml.description strip_tags(b.rich_text_body.to_s.gsub(/\r\n|\r|\n|\s|\t/, "")).truncate(120)
          xml.image image_url(url_for(b.image))
          xml.pubDate b.time.to_s(:rfc822)
          xml.link blog_url(b)
          xml.guid blog_url(b)
        end
      end
    end
  end
end

https://pgmg-rails.com/blogs/24 
を参考にします。

cloud9の構文チェックの色がつかなくなりました。拡張子なのか原因は分かりませんでした。

app/views/rsss/index.rss.builder
         xml.title b.content
          xml.description b.content
          xml.image image_url(url_for(b.picture)) if b.picture?
          xml.pubDate b.updated_at.to_s(:rfc822)

RSSが出力されるか確認

RSSが出力されるかを確認してみます。

rails serverで、/rssにアクセスします。
https://XXXXXXXXXXXXXXX.amazonaws.com/rss

エラーが出力されました。

ActionController::RoutingError (uninitialized constant RssController):

routesを確認します。

buntu:~/environment/sample_app (rss) $ rails routes
                 Prefix Verb   URI Pattern                             Controller#Action
                   root GET    /                                       static_pages#home
...
                    rss GET    /rss(.:format)                          rss#index {:format=>:rss}

複数形とファイル名が合っていないのが問題かとあたりをつけました。
routesのstatic_pages#homeにはファイル名がstatic_pages_controller.erbが対応しています。
なのでrss#indexにはファイル名がrss_controller.erbが対応するのではと考えました。
だとするとroutesがrsss#indexであるべきなので、修正します。

config/routes.rb
  get :rss, to: 'rsss#index', defaults: { format: :rss }

違うエラーが出力されました。

ActiveRecord::RecordNotFound (Couldn't find User with 'id'=):
app/controllers/rsss_controller.rb:5:in `index'

先のエラーは解消されコントローラーに進みました。
ログインしていないので、userのidがないためです。

試しにログインしてからアクセスしてみましたが、同じエラーでした。

原因として、パラメーターからidがなぜ取れないのか、
そもそもRSSを取得するときにはログインしていないので、user#showを参考にします。

GET    /users/:id(.:format)  users#show

になっています。urlでxxx/users/1 にアクセスするとidに1が渡されてきます。
routesに/:idを追加すればよいのではと考え、修正します。

ネットでroutesの書き方を調べます。
https://www.sejuku.net/blog/13078

config/routes.rb
  get 'rss/:id', to: 'rsss#index', defaults: { format: :rss }
ubuntu:~/environment/sample_app (rss) $ rails routes
                 Prefix Verb   URI Pattern                             Controller#Action
                   root GET    /                                       static_pages#home

                        GET    /rss/:id(.:format)                      rsss#index {:format=>:rss}

違うエラーになりました。

ActionView::Template::Error (undefined method `blog_url' for #<#<Class:0x000056130c6fb330>:0x000056130c6f9648>
Did you mean?  login_url):

例として参考にした記事のそのままだと動かない点だと分かりました。
linkとguidには何が表示されるべきなのか調べます。

          xml.link blog_url(b)
          xml.guid blog_url(b)

参考にした記事はブログの例であり、各記事のURLを指定していました。
対応するものとして、マイクロポストごとのURLはないので、ユーザーのURLを出すことにします。pathとURLの違いがあいまいだったのでネットで確認しました。
https://qiita.com/higeaaa/items/df8feaa5b6f12e13fb6f

app/views/rsss/index.rss.builder
          xml.link user_url(b.user)
          xml.guid user_url(b.user)

修正してurlにアクセスしたところ、開くか保存するかのダイアログが表示されました。

rss.1.png

保存したファイルをメモ帳で開いたところ、xmlが出力されていました。

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Rails Tutorial sample site</title>
    <description>Rails Tutorial sample site</description>
    <link>https://xxxxxxxxxxxxxxxxxxxxx.amazonaws.com/</link>
    <item>
      <title>@Elvis1 reply test</title>
      <description>@Elvis1 reply test</description>
      <pubDate>Wed, 11 Nov 2020 23:27:05 +0000</pubDate>
      <link>https://xxxxxxxxxxxxxxxxxxxxx.amazonaws.com/users/1</link>
      <guid>https://xxxxxxxxxxxxxxxxxxxxx.amazonaws.com/users/1</guid>
    </item>
    <item>
      <title>Est et placeat voluptates et alias.</title>
      <description>Est et placeat voluptates et alias.</description>
      <pubDate>Wed, 11 Nov 2020 23:27:04 +0000</pubDate>
      <link>https://xxxxxxxxxxxxxxxxxxxxx.amazonaws.com/users/1</link>
      <guid>https://xxxxxxxxxxxxxxxxxxxxx.amazonaws.com/users/1</guid>
    </item>
..
    <item>
      <title>Sint porro molestiae corporis quidem eligendi.</title>
      <description>Sint porro molestiae corporis quidem eligendi.</description>
      <pubDate>Wed, 11 Nov 2020 23:27:03 +0000</pubDate>
      <link>https://xxxxxxxxxxxxxxxxxxxxx.amazonaws.com/users/1</link>
      <guid>https://xxxxxxxxxxxxxxxxxxxxx.amazonaws.com/users/1</guid>
    </item>
  </channel>
</rss>

このURLをFeedlyに試しに追加してみたのですが、RSSとして認識されませんでした。

We were not able to find an RSS feed for https://xxxxxxx.amazonaws.com/rss/1.

Please contact the website and ask them if they offer a valid RSS feed.

RSSの問題なのかネットで調べましたがよく分かりませんでした。

https://qiita.com/amymd/items/bb4a9e008af061c89ea9

https://pgmg-rails.com/blogs/24
を参考にコントローラーの書き方を変更してみます。

app/controllers/rsss_controller.rb
    respond_to do |format|
      format.html
      format.rss { render :layout => false }
    end

ファイルを開くダイアログが表示される動きは変わりませんでした。
ネットで調べましたが分からなかったので、いったんそのままにします。

ステータスフィードを出力するように変更

今は自分がポストしたものを出力しているので、ステータスフィード、つまりフォローしている人も含むポストを、RSSフィードで出力する機能に変更します。

ステータスフィードを画面に表示しているところを参考にします。
ホーム画面でしたので、static_pagesコントローラーとあたりを付けます。

app/controllers/static_pages_controller.rb
@feed_items = current_user.feed.paginate(page: params[:page])

を見つけ、feedメソッドで出力できると分かります。コンソールで試してみると、確かにマイクロポストが返ってきました。
コントローラーを変更します。

app/controllers/rsss_controller.rb
class RsssController < ApplicationController
  def index
    @user = User.find(params[:id])
    @microposts = @user.feed.limit(10) 

    respond_to do |format|
      format.html
      format.rss { render :layout => false }
    end
  end
end

rails serverで動かしてみます。ファイルが出力されるので内容を確認します。

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Rails Tutorial sample site</title>
    <description>Rails Tutorial sample site</description>
    <link>https://https://xxxxxxxxxxxxxxxxxxxxx.amazonaws.com.amazonaws.com/</link>
    <item>
      <title>@Elvis1 reply test</title>
      <description>@Elvis1 reply test</description>
      <pubDate>Wed, 11 Nov 2020 23:27:05 +0000</pubDate>
      <link>https://https://xxxxxxxxxxxxxxxxxxxxx.amazonaws.com.amazonaws.com/users/1</link>
      <guid>https://https://xxxxxxxxxxxxxxxxxxxxx.amazonaws.com.amazonaws.com/users/1</guid>
    </item>
    <item>
      <title>Est et placeat voluptates et alias.</title>
      <description>Est et placeat voluptates et alias.</description>
      <pubDate>Wed, 11 Nov 2020 23:27:04 +0000</pubDate>
      <link>https://https://xxxxxxxxxxxxxxxxxxxxx.amazonaws.com.amazonaws.com/users/6</link>
      <guid>https://https://xxxxxxxxxxxxxxxxxxxxx.amazonaws.com.amazonaws.com/users/6</guid>
    </item>

  </channel>
</rss>

ホーム画面と突き合わせてみると、ポストの2つ目は他のユーザーがポストしたもので合っていました。

rss.2.png

RSSでは誰がポストしたマイクロポストなのかが分からないということが分かりました。今回はそのままにして、今後の改善点としておきます。

テストを作成

動くようになりましたので、テストを書きます。RSSの出力結果をどう扱えばよいのかが分からないのでネットで調べましたが見つかりませんでした。なので画面と同じように書くことにします。

test/integration/rss_test.rb
require 'test_helper'

class RssTest < ActionDispatch::IntegrationTest

  def setup
    @user = users(:michael)
  end

  test "rss show" do
    get rss_path(@user)
    assert_template 'rsss/index'
  end

end

エラーになりました。

NoMethodError:         NoMethodError: undefined method `rss_path' for #<RssTest:0x000055fc3d47d0f8>

ubuntu:~/environment/sample_app (rss) $ rails routes
                 Prefix Verb   URI Pattern                             Controller#Action
                 new_dm GET    /dms/new(.:format)                      dms#new
                     dm DELETE /dms/:id(.:format)                      dms#destroy
                        GET    /rss/:id(.:format)                      rsss#index {:format=>:rss}

rss_pathのルーティングには、Prefixのところに名前がなく空白ないので、名前をつけてみます。
https://www.sejuku.net/blog/13078 
を参考にします。

config/routes.rb
get 'rss/:id', to: 'rsss#index', as: 'rss', defaults: { format: :rss } 
ubuntu:~/environment/sample_app (rss) $ rails routes
                 Prefix Verb   URI Pattern                             Controller#Action
                     dm DELETE /dms/:id(.:format)                      dms#destroy
                    rss GET    /rss/:id(.:format)                      rsss#index {:format=>:rss}

GREENになりました。

contentが表示されているかをassert_matchで調べるように追加します。テストを実行したところGREENでした。
これで完成とします。

test/integration/rss_test.rb
  test "rss show" do
    get rss_path(@user)
    assert_template 'rsss/index'
    @user.feed.limit(10).each do |micropost|
      assert_match micropost.content, response.body
    end
  end

いつものようにherokuにアップします。

ubuntu:~/environment/sample_app (rss) $ git add -A
ubuntu:~/environment/sample_app (rss) $ git commit -m "Add RSS"       
ubuntu:~/environment/sample_app (rss) $ git checkout master
ubuntu:~/environment/sample_app (master) $ git merge rss
ubuntu:~/environment/sample_app (master) $ git push
ubuntu:~/environment/sample_app (master) $ git push heroku

HerokuでRSSのURLにアクセスしてみました。ファイルを開くダイアログが表示される動きは変わらなかったです。

所要時間

12/21から1/11までの実働13日間の8.0時間です。
ネットで調べるのに時間がかかりました。書いたりテストしたりの時間は、感覚的に半分もかかっていないです。

参考にした記事のまとめ

http://miner.hatenablog.com/entry/2017/07/20/142532

https://pgmg-rails.com/blogs/24

https://qiita.com/klriutsa/items/6662ef75e804c4323228

https://madogiwa0124.hatenablog.com/entry/2019/02/24/234610

http://maepachi.com/entries/94

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

RailsでSlick使ったらTurbolinksで競合した。

Slickを業務で使用したところ、
Turbolinksの影響で初回読み込み時にスライド全体が右に寄ってしまう。
という現象が起きていたので解消した方法を残しておきます。

環境

  • Rails5

  • jquery-slick-rails

jquery-slick-railsというgemを使用していますが、
これを入れる前に本家からダウンロード版入れて実装していました。
この時にも同じ現象が起きていたのでツールのせいではないと思われます。

状況

silickの設定でcenterMode: trueにしたところ、
ページの初回読み込み時(正確にはcookieにログが残っていない時)に、
スライド画像が全体的に右に寄ってしまう。というものです。

centerModeではない時にはきちんと表示されるので、
なぜこの時だけなのかはすみませんがわかりません。
もしわかる方いらっしゃいましたらぜひ教えてください。

色々調べた結果、Turbolinksが関係しているとわかりました。

対処法

まず最初に解決した方法を記述します。
対象ページをTurbolinksを使用しないようにします。

<%= link_to url, data: { 'turbolinks': false } %>

に飛ぶリンクに対してdata-turbolinks="false"をつけて、
そのページだけTurblinksをオフにします。
link_toに直接属性を追加していますが、
リンクを囲むdivタグを設置してこちらに属性を追加しても良いようです。

Turbolinksとは相性が悪そうですね。
Railsで使用する時には対策打っておいた方が良さそうです。

その他の試した方法

  • require turbolinksを削除する

これは本当にTurbolinksのせいなのかを確認した時に使った方法です。
基本的にはこちらはやらない方が良いでしょう。

  • turbolinks: loadを使う
$(document).on('turbolinks: load', () => {
    $('#selector').slick({
        centerMode: true
    });
})

これは基本だと思うんですが、
今回はこれをやってもダメでした。
書き方が間違ってたのかな. . .??
こういうとこちゃんとわかってないないところに勉強不足を感じます。

今回参考にさせて頂いた記事はこちらです。
Rails Turbolinksをページ毎に無効化する方法
ありがとうございました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【これを知りたかった】Docker+RailsでRSpec導入〜トップページ表示確認テストの書き方まで

背景

  • Railsのポートフォリオ作成で、RSpecの導入を検討
  • 導入から、トップページの表示を確認するテストの書き方までをまとめました

1. Gemのインストール

GemfileにRails用のrspecとfactory_botのgemを加える

Gemfile
group :development, :test do
  gem "rspec-rails"
  gem "factory_bot_rails"
end

Dockerでbuildし直す

docker-compose build

2. rspecの導入

以下のコマンドでRailsアプリに、rspecを導入

$ bundle exec rails generate rspec:install
      create  .rspec
      create  spec
      create  spec/spec_helper.rb
      create  spec/rails_helper.rb

3. rspecの生成ファイルの定義

  • 設定ファイルはconfig/application.rb
  • falseをつけると不要なテストファイルは作成されなくなる
config/application.rb
config.generators do |g|
  g.test_framework :rspec, 
        # 不要なテストファイルは以下のようにfalseをつけて書く
        view_specs: false, 
        helper_specs: false, 
        controller_specs: false, 
        routing_specs: false
end

4. Viewをテストしてみる

Viewテスト用のrspec作成

rails g rspec:view Homes

ただ、これだけだと/spec/views/homes/というフォルダしか作成されない

テスト用のファイル作成

/spec/views/homes/以下にindex.html.erb_spec.rbを作成し、以下を記述

/spec/views/homes/index.html.erb_spec.rb
require 'rails_helper'

RSpec.describe "homes/index", type: :view do
  it 'should display top page' do
    visit "/"
    expect(page).to have_content 'こされ'
  end
end

以下補足
* visit "/" : ルートに遷移
* expect(page).to have_content '文字列' : 現在の表示ページ上に"文字列"があることを確認

テスト実行

$ rspec

homes/index
  should display top page

Finished in 24.64 seconds (files took 7.02 seconds to load)
1 example, 0 failures

0 failuresなので、テストが成功

RSpecで「NoMethodError: undefined method `visit' for ~ 」と怒られた時

spec/spec_helper.rb
...

require 'capybara/rspec'

RSpec.configure do |config|
  config.include Capybara::DSL # 追記

...

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

単一ファイルコンポーネントの原則をrails6のアプリに組み込んでみた。いまいちよくわからん。

単一ファイルコンポーネントの原則

コンポーネントごとにvueファイルを作成する開発の進め方のこと。つまりパーツ単位でHTMLをまとめてコンポーネントとして扱いどこでも呼び出せるようにすること、を指すと考えて良さそう。

これの反対をグローバルコンポーネント、といい

new Vue({ el: '#container '})

といった形でcontainerをターゲットにしたvueファイルを作り、各ページで読み込む。この書き方は小規模開発では優れているが、大規模な開発になるといくつか不具合が生じる。中でも全てのコンポーネントの変数定義が共通になるのはちょっと避けたい。よって使用するHTMLごとにコンポーネント化する単一ファイルコンポーネントの原則に従って開発するのがベター。

単一コンポーネントでvueファイルを書くとこんな感じ

<template>
  <div class="side_bar">SideBar</div>
</template>

<script>
</script>

<style>
 .side_bar {
  width: 300px;
  background-color: green;
}
</style>

templateの部分にHTML、scriptでjs、styleでcssを指定する。これをHTML部品ごとに作る。こうすると部品ごとに一つのファイルで扱えるのでやり直しがしやすい。またこのクラスにあたってるcssどれ?みたいな疑問もなくなる。

作ったコンポーネントをrailsアプリで読み込むわけだが今回は

各コンポーネントを読み込む親のjsがエントリーファイルとなっている。こいつをbuildしてrailsアプリで読み込むと各コンポーネントの設定がアプリに反映される仕組み。

main.js(エントリーファイル)

import Vue from 'vue';
import App from './App.vue';

// App.vueをエントリとしてレンダリング
new Vue({
  el: '#app',
  render: h => h(App)
})

App.vue(親コンポーネント)

<template>
  <div class="container">
    <sidebar></sidebar>
    <chat-container></chat-container>
  </div>
</template>

<script>
import Sidebar from './components/Sidebar.vue'
import ChatContainer from './components/ChatContainer.vue'

  export default {
    components:{
      Sidebar,
      ChatContainer
    }
  }
</script>

<style>
.container {
  display: flex;
  margin: auto;
  width: 70%;
  height: 100vh;
}
</style>

こいつをwebpackでコンパイルする。webpack.config.jsは以下の通り

module: {
    rules: [
      {
        test: /\.vue$/,
        exclude: /node_modules/,
        loader: 'vue-loader'
      },
      {
        test: /\.css$/,
        exclude: /node_modules/,
        use: ['style-loader', 'css-loader'],
      },
    ]
  },
    (省略)
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js' // 'vue/dist/vue.common.js' for webpack 1
    }
  },
  plugins: [new VueLoaderPlugin()]

重要なのはloaderとresolveオプションかなと思うので関係ないところ
は省略。ちょっとハマったのはcss-loaderとstyle-loaderを読み込む際にはなぜかloaderオプションじゃなくてuseオプションにしないといけなかったこと。複数loaderを読み込むからなのかな?

コンパイル後にrailsサーバーを立ち上げると画像のように別々のファイルに書いたhtmlとcssがきっちり反映されて一つのビューにまとまっていることがわかる。

ChatVueApp_と_20200111_md.png

参考

・単一ファイルコンポーネントについての公式ドキュメント

https://jp.vuejs.org/v2/guide/single-file-components.html

・単一ファイルコンポーネントをwebpackを使って実現する方法について

https://qiita.com/tkhr/items/ac22019c891fe8fa5f91

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Formオブジェクトを作成するために、ActiveModel::Modelをincludeする理由

概要

  • ActiveModel::Modelとは
  • ApplicationRecordを継承するのだとだめなのか
  • 参照

ActiveModelとは

Action PackやAction Viewと連携する機能を使えるようになる。

Railsガイドによると、モデル名の調査、変換、翻訳、バリデーションといった機能が使えるようになるみたいです。
またActive Recordの場合と同じような方法で、オブジェクトを属性のハッシュで初期化することができるようになります。

コードで記述すると

model
class NameList
  include ActiveModel::Model

  attr_accessor :name, :email, :prefecture

  validates :name, :email, :prefecture
end
 name_list = NameList.new(name: "Tarou", email: "tarou@example.com", prefecture: "青森")

  name_list.name # => "Tarou"
  name_list.email # => "tarou@example.com"
  name_list.prefecture # => "青森"

ざっくりな解釈ですが
定義した属性値にバリデーションをかけられて、また属性値をハッシュのキーに持つインスタンスを生成することができるみたい。

ここで一つの疑問が生まれました。
同じような機能をすでに持っているApplicationRecordクラスを継承すればいいのでは?と

ApplicationRecordを継承するのだとだめなのか

結論、フォームを用意しているViewに遷移すると、エラーが起きます。

ActiveRecord::StatementInvalid
Mysql2::Error: Table 'sample_app_development.name_lists' doesn't exis

エラー原因は、モデルに紐づくテーブルが存在しないことによるものだと考えられます。

ApplicationRecordの親である、ActiveRecord::Baseにモデルとテーブルを1対1で紐付ける機能がありそうです。

ActiveModel::Modelをincludeする理由は、機能実装に必要なメソッドの取得を最小限に留めるためだと考えます。

Formオブジェクトを作成するときはデザインパターン通りにコードを記述するのが良さそう。
疑問が浮かべばあえてエラーを起こして原因を探るのも面白そうです。
何か誤りがありましたらご教示いただけると幸いです。

参照

  • Railsガイド
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Railsデプロイ with Docker

参考サイト

Docker超入門 :きよとのプログラミング大学

参照

Rails環境構築 with Docker
こちらでDockerを使用したRailsの環境構築までを行っております。

Docker 用語とコマンド
Dockerについての用語やコマンドについてはこちらをご覧ください

環境

Mac OS
docker-compose 1.27.4
heroku/7.47.7
Mysql 8.0
ruby 2.7
rails 6.1.0

heroku実装

herokuログイン

terminal.
rails_on_docker % heroku login
heroku: Press any key to open up the browser to login or q to exit:  //Enterキーでログイン
rails_on_docker % heroku container:login

herokuアプリ作成

terminal.
rails_on_docker % heroku create <rails-koumori>  // < >内は任意の名前を指定

データベース追加・設定

データベースの追加

terminal.
rails_on_docker % heroku addons:create cleardb:ignite -a rails-koumori 

本番環境の接続先情報を環境変数に修正

database.yml
production:
  <<: *default
  database: <%= ENV['APP_DATABASE_DATABASE'] %>
  username: <%= ENV['APP_DATABASE_USERNAME'] %>
  password: <%= ENV['APP_DATABASE_PASSWORD'] %>
  host: <%= ENV['APP_DATABASE_HOST'] %>

接続先情報を環境変数に設定

terminal.
rails_on_docker % heroku config -a rails-koumori
CLEARDB_DATABASE_URL: mysql://ユーザー名:パスワード@ホスト名/データベース名?reconnect=true

rails_on_docker % heroku config:add APP_DATABASE='データベス名'-a rails-koumori
rails_on_docker % heroku config:add APP_USERNAME='ユーザー名' -a rails-koumori
rails_on_docker % heroku config:add APP_PASSWORD='パスワード' -a rails-koumori
rails_on_docker % heroku config:add APP_HOST='ホスト名' -a rails-koumori

rails_on_docker % heroku config -a rails-koumori  //登録の確認

本番環境用の記述

空のファイル作成

terminal.
rails_on_docker % touch start.sh  
start.sh
#!/bin/sh

# 本番環境
if [ "${RAILS_ENV}" ="production" ]
then
    bundle exec rails assets:precompile
fi

bundle exec rails s -p ${PORT:-3000} -b 0.0.0.0

Dockerfileの追記

Dockerfile
# ベースイメージの指定
FROM ruby:2.7

#追記
ENV RAILS_ENV=production  
.
.
.
.

#dockerにコピー
COPY start.sh /start.sh  
#実行権限を付与
RUN shmod 744 /start.sh  
#起動時に実行
CMD ["sh","/start.sh"]   

本番環境に適用

terminal.
rails_on_docker % heroku config:add RAILS_SERVE_STATIC_FILES="true" -a r
ails-koumori  //本番環境にassets:precompileを適用

rails view画面実装

コントローラー作成

terminal.
rails_on_docker % docker-compose exec web bundle exec rails g controller users 

トップページにusers/indexを指定

routes.rb
Rails.application.routes.draw do
  get '/',to: "users#index"
end

コントローラーの記述

users.controller.rb
class UsersController < ApplicationController
  def index
  end
end

index.html.erbファイルを作成し記述

src>app>views>users>index.html.erb
<h1>Hello world!</h1>

Dockerコンテナのプッシュとherokuへのリリース

Dockerイメージをビルドしコンテナにプッシュ

terminal.
rails_on_docker % heroku container:push web -a rails-koumori

herokuにコンテナをリリース

terminal.
rails_on_docker % heroku container:release web -a rials-koumori

herokuを起動しブラウザで確認

terminal.
rails_on_docker % heroku open -a rails-koumori

スクリーンショット 2021-01-10 18.13.47.png

まとめ

前回のRails構築から、今回でデプロイまで完了できました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Ruby on Rails】RailsでのBootstrapの導入方法

Bootstrapとは

・Teitter社が開発したCSSのフレームワークの事です。
・サイトのデザインを簡単に作成することができます。
・よく使われるスタイルがあらかじめ定義されているので、定義されたルールに従って利用すれば整ったデザインのページを作成できます。

Bootstrapの導入方法

1.gemを追加する

Bootstrapを使用する為に、以下gemを追加します。
・bootstrap-sass

Gemfile
gem 'bootstrap-sass', '3.4.1' 

Gemfileに書き込み、bundle installを実行します。
コマンド実行後、最後に「Bundle complete!」という文字列を含む節が表示されればインストール完了です。

2.ファイルにbootstrapを読み込ませる

Bootstrapを適用させたいcssファイルを選択します。
その後、以下のようにコードを入力します。

※cssファイルでは、「//」でコメントアウトすることができます。

example.css
//bootstrap-import
@import "bootstrap-sprockets";
@import "bootstrap";

コードを入力し終えたら、拡張子を「css」から「scss」に変更します。

example.scss
//bootstrap-import
@import "bootstrap-sprockets";
@import "bootstrap";

以上で、bootstrapの導入は終わりです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む