かきたくぶろぐ

凡人目線の素人ぶろぐ

プログラミング未経験のHTMLコーダーがRailsチュートリアルをやってみた - 2章

Toyアプリケーション制作

いよいよコードを書く時が!
scaffoldジェネレータというスクリプトを使って生成。

scaffoldジェネレータとは?
簡単にアプリケーションの雛形を生成してくれるもの

アプリケーションの計画

何事も計画が大切ですものね。 rails newでver5.1.6の骨組みを生成。

$ rails _5.1.6_ new toy_app

1章でもやったGemfileの編集。
(同じ記述)
本番環境のgemをインストールしないようにする為--without productionをつけてローカルgemをインストール

$ bundle install --without production

最後にGitでコミットまで。
toy_appリポジトリを作りpushしようと思ったのだがここで問題が。
自分はRails-tutorialという大きなくくりのリポジトリの中で、チュートリアルで使うファイルだったりを管理しようとしていたのだけど、今回のフローだとRails-tutorialリポジトリにtoy-appという別のリポジトリを作ることになってしまう。
しかしGitにはsubmoduleという外部リポジトリを取り込む機能があるらしい! 参考
無事解決!

$ git remote add origin リポジトリURL
$ git push -u origin --all

-uって?
-u, --set-upstream
上流ブランチを一緒に設定するオプション
これを記述してpushすると、次回以降git pushだけで-uを使用したブランチにpushできる&上流ブランチとして認識される

じょうりょうぶらんちってなによ

上流ブランチ
ローカルのブランチが履歴を追跡するように設定したリモートブランチ
参考

要はローカルのmasterブランチさん、リモートリポジトリのorigin/masterをちゃんと追跡しなさいね!ってことかな?

かなりうっすらとした理解だけど次に進む。

Applicationコントローラーにhelloアクションの追加

def hello
  render html: "hello, world!"
end

rubyrailsも初心者なので少しでもわからないのは調べます。
def...メソッドを定義する際に使用 render...Action内で呼び出すViewを指定するメソッド ルートのルーティングを設定。

root 'application#hello'

コミットしてHerokuにpush。

$ git commit -am "Add hello"
$ heroku create
$ git push heroku master

Webアプリケーションを作る際、アプリケーションの構造を表すためのデータモデルを最初に作成しておくのが普通です。

な、なるほど(@_@)

モデル設計

ユーザーのモデル設定

integrer型のID番号と、string型の名前(name)、メールアドレス(email)を持たせる

マイクロポストのモデル設計

idとマイクロポストのテキスト内容を格納するtext型のcontent、されにユーザーと関連付ける為user_idで構成。

Usersリソース

scaffold再び。 データモデルをscaffoldジェネレータで生成するのか!しかもscaffoldジェネレータは全てのRailsプロジェクトに標準搭載されているときた!
rails generateスクリプトscaffoldコマンドを渡して生成。
scaffoldコマンドの引数にデータモデルの属性をオプションにしてパラメータを追加。

$ rails generate scaffold User name:string email:string

rails db:migrateを実行してデータベースをマイグレート (migrate)

$ rails db:migrate

マイグレート (migrate) って?
SQL文を書かずにデータベースの構造を変更でき、マイグレーションファイルを実行することにより、その内容に基づいたデータテーブルを生成してくれる

Rails5より前のバージョンではdb:migrateコマンドはrailsではなくてrakeコマンドが使われていた為、古いRailsアプリケーションの場合は要注意。

サーバーを起動。

$ rails server

ユーザーページを探検

Usersリソースをscaffoldで生成したので、ユーザー管理用のページが多数追加されている。 (/Usersを表示すればユーザー一覧が表示される、など) バリデーションとかの実装はこれからみたいだけど、こんな簡単に骨組みができるのか。

MVCの挙動

単語とうっすらとした役割しか知らなかったので、ここでちゃんと学ばねば。 スクリーンショット 2018-10-17 0.54.29.png (334.8 kB) うーんむずかしい。
ルーティングファイルを設定することでアクションを制御できるのかな?
デフォルトページをusersページに書き換える。

Rails.application.routes.draw do
  resources :users
  root 'users#index'
end

scaffoldで生成したusersコントローラーにはすでにいろいろなアクションが記述されている。
同じようなアクションでもHTTP requestメソッドが違う為用途がちがう。

show...GET
update...PATCH

indexアクションに@users = User.allという記述があり、これは@users変数にUserモデルから全てのユーザー一覧を取り出し格納するという記述。
@***でインスタンス変数を定義できる。
次にコントローラーがビューを呼び出す。

<% @users.each do |user| %>
  <tr>
    <td><%= user.name %></td>
    <td><%= user.email %></td>
    <td><%= link_to 'Show', user %></td>
    <td><%= link_to 'Edit', edit_user_path(user) %></td>
    <td><%= link_to 'Destroy', user, method: :delete,
                                     data: { confirm: 'Are you sure?' } %></td>
  </tr>
<% end %>

@usersの数だけhtmlを繰り替し表示しなさいよーって記述。

現在のUsersリソースの欠点

  • 空欄でも通ってしまう
  • 認証機能がない
  • テストが書かれていない
  • 見た目(スタイル)が整っていない
  • 理解が難しい

Micropostsリソース

次はこちら。scaffoldでコードを生成。

$ rails generate scaffold Micropost content:text user_id:integer

新しいデータモデルでデータを更新するバメマイグレーションを実行。

$ rails db:migrate

おー、フォルダを見ると新しいファイルが追加されている。
resources :micropostsというルーティングルールも追加されている。

Rails.application.routes.draw do
  resources :microposts
  resources :users
  root 'users#index'
end

マイクロポストをマイクロにする

app/models/micropost.rbに文字数制限の記述を追加。

class Micropost < ApplicationRecord
  validates :content, length: { maximum: 140 }
end

ユーザーはたくさんマイクロポストを持っている

1人のユーザーに複数のマイクロポストがある has_manyメソッド(1対複数の関連付け)

# app/models/user.rb
class User < ApplicationRecord
  has_many :microposts
end

1つのマイクロポストは1人のユーザーのみ属する belongs_toメソッド(1対1の関連付け)

# app/models/micropost.rb
class Micropost < ApplicationRecord
  belongs_to :user
  validates :content, length: { maximum: 140 }
end

rails consoleを使用し、関連付けを確認

$rails console

User.firstで1人目のユーザー情報にアクセスできる

>> first_user = User.first
=> #<User id: 1, name: "Michael Hartl", email: "michael@example.org",
created_at: "2016-05-15 02:01:31", updated_at: "2016-05-15 02:01:31">

>> exitで終了

バリデーションを更に追加。
マイクロポストのContextが存在しているか検証。

# app/models/micropost.rb
class Micropost < ApplicationRecord
  belongs_to :user
  validates :content, length: { maximum: 140 },
              presence: true
end

presenceメソッドを使用し空でないことを確認。
同じくUsersのnameとemailも。

# app/models/user.rb
class User < ApplicationRecord
  has_many :microposts
  validates :name, presence: true
  validates :email, presence: true
end

継承の改装

なんとなく気づいてはいたけど、Rubyでの継承は<記号で行う。

class User < ApplicationRecord
end

UserモデルとMicropostモデルはいずれも、ApplicationRecordというクラスを継承している。
ApplicationRecordは ActiveRecord::Baseを継承している。
ActiveRecord::Base を継承したから各モデルはデータベースにアクセスでき、データベースのカラムをRuby属性のように使える。
コントローラーも元をたどるとActionController::Baseクラスを継承している。

アプリケーションをデプロイ

herokuにログインしpush

$ git push heroku

アプリケーションのデータベースを動作させるために、次の$ heroku runコマンドを実行して本番データベースのマイグレーションを行う。

$ heroku run rails db:migrate

おー!ちゃんと反映されている! バリデーションも問題なく機能している! よかったよかった。

初めてのものばかりで戸惑いも多いけど、焦らず積み上げていこうと思います。
実際動くものが出来上がると嬉しいものですね。

いざ3章へ!

プログラミング未経験のHTMLコーダーがRailsチュートリアルをやってみた - 1章

なぜはじめたの?

現在のスキル(2018/10)

  • HTML(pug) / CSS(sass) → 業務で使用経験あり。
  • JavaScript → 個人的に学習はしているが、業務での使用経験は無し。
  • Ruby/Ruby on Rails → 知識ゼロ。
  • GIt → 業務で使用経験あり。

まとめると、Gitが使えてHTMLとCSSだけは書けるが他は業務経験が全くない、といった感じです。

早速はじめてみよう!

Ruby on Rails とは

Rubyプログラミング言語で記述された、Web開発フレームワーク

開発環境

チュートリアルではAWS Cloud9が推奨されていたが、できそうだったのでローカルで構築する。
以下構築手順 (※Homebrewインストール済)

rbenvインストール

$ brew install rbenv

.bash_profileにパスを通す。

$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'if which rbenv > /dev/null; then eval "$(rbenv init -)"; fi' >> ~/.bash_profile

.bash_profileってなんぞ?
ログインシェル(PCを起動したときにデフォルトに指定されるシェル)をbashにしている場合はログイン(起動)時に以下のような順番で設定ファイルが読み込まれ、PATHを通す、エイリアスを定義する、プログラムを実行するなどの設定が自動で設定される。
参考サイト

以下もインストール

$ brew install ruby-build
$ brew install rbenv-gemset

readlineのインストール

$ brew install readline

readlineってなんぞ?
ターミナル上でrubyのコマンドを打つことの出来るirbで、日本語を使えるようにします。
参考サイト
irbとは

Rubyのインストール

Rubyの公式サイトに行き、安定版のバージョンを確認。
https://www.ruby-lang.org/ja/downloads/

インストール

$ rbenv install [バージョン]

rbenv の再読み込み

$ rbenv rehash

defaultで使うrubyバージョンを指定

$ rbenv global [バージョン]

Railsのインストール

バンドルインストール

$ gem install bundler --no-document

Railsインストール(現在チュートリアルで使用している5.1.6をDL)

$ gem install rails --version="5.1.6" --no-document

--no-documentとは ドキュメントをインストールしない設定 インストールをはやくする

最新版を入れている場合はチュートリアルに合わせて他バージョンをインストール

ローカルにあるRailsバージョンを確認

$ gem list rails

バージョンを指定してインストール(5.1.6をインストール)

$ gem i -v 5.1.6 rails

チュートリアルで使用するディレクトリに移動し、バージョンを指定してrailsアプリケーションを新規作成

rails _5.1.6_ new hello_app

railsバージョン5.1.6を使用したhello_appフォルダが作成される。

Bundlerを実行して必要なGemをインストール

Bunderとは?
Gemパッケージの管理に使用

じゃあGemとは?
Ruby言語用のパッケージ管理システム

バージョン管理の仕組み

特定のバージョンを指定しない場合

最新のものがインストールされる。

>= 1.3.0で指定した場合

1.3.0以上であれば最新バージョンがインストールされ、それ以下の場合は最新のものがインストールされる

~> 4.0.0で指定した場合

バージョンが4.0.0より大きく、4.1より小さい場合にインストールされる。
マイナーバージョンの更新のみアップグレードされる。

チュートリアルに記述してあったGemfileを丸っとコピペ。

source 'https://rubygems.org'

gem 'rails',        '5.1.6'
gem 'puma',         '3.9.1'
gem 'sass-rails',   '5.0.6'
gem 'uglifier',     '3.2.0'
gem 'coffee-rails', '4.2.2'
gem 'jquery-rails', '4.3.1'
gem 'turbolinks',   '5.0.1'
gem 'jbuilder',     '2.6.4'

group :development, :test do
  gem 'sqlite3',      '1.3.13'
  gem 'byebug', '9.0.6', platform: :mri
end

group :development do
  gem 'web-console',           '3.5.1'
  gem 'listen',                '3.1.5'
  gem 'spring',                '2.0.2'
  gem 'spring-watcher-listen', '2.0.1'
end

# Windows環境ではtzinfo-dataというgemを含める必要があります
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

appディレクトリでbundleインストール

$ bundle install

railsサーバーを起動。 (別のターミナル画面で実行するのが推奨)

$ rails server

Yay! You're on Rails!!!!!!!!!!!!

Model-View-Controller(MVC)

railsの採用しているアーキテクチャパターン
rubyrailsも初心者だけどMVCは聞いたことある。
チュートリアルを進めるとこのパターンが体験できる...のか?

Hello, world!

いつもここからはろーわーるど。
Applicationというコントローラーに表示したい文字列を返すhelloアクションを作成。

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

  def hello
    render html: "hello, world!"
  end
end

次にデフォルトページ(Yay! You're on Rails!!!!!!!!!!!!)の代わりにこのhelloアクションを使用するように書き換える。
ルーター (router)を編集。

# config/routers.rb
Rails.application.routes.draw do
# コントローラー名:application,アクション名:hello
  root 'application#hello'
end

ルーターとは コントローラーとブラウザの間に配置され、ブラウザのリクエストをコントローラーに振り分け(=ルーティング)をする。

hello, world!

Git

ここでは割愛。

デプロイ

昔はデプロイ作業は大変だったみたいだけど、ここ数年で簡単になったみたい!素敵!
チュートリアルではHerokuを使ってデプロイする。

Herokuのセットアップ

PostgreSQLデータベースを使用。
そのために本番環境にpg gemをインストールして、PostgresSQLと通信できるようにする。

group :production do
  gem 'pg', '0.20.0'
end

HerokuはSQLiteがサポート外の為、sqlite3 gemが本番環境に導入されないよう設定。

group :development, :test do
  gem 'sqlite3', '1.3.13'
  gem 'byebug',  '9.0.6', platform: :mri
end

言われるがまま行う。 開発環境/本番環境で使う物をきっちりわけ無駄なものは導入しないようにってことかな。
(間違えてサポート外のものを導入した場合はどうなるのだろうか)
本番用のgemをローカルにはインストールしないようにする為---without productionをつけてbundle install

$ bundle install --without production

なぜ今またbundle install?
pg gemを追加したことやRubyバージョンを指定したことをGemfile.lockに反映させないと、本番環境へのデプロイで失敗してしまうため

変更内容をコミット。
Herokuのユーザー登録を行い、インストール

$ brew install heroku/brew/heroku

インストール確認。

$ heroku --version

herokuコマンドでログインしてSSHキーを追加。

$ heroku login
$ heroku keys:add

heroku createコマンドを実行し、Herokuサーバーにサンプルアプリケーションの実行場所を作成。

$ heroku create

herokuにデプロイする

$ git push heroku master

hello, world!

...簡単!
人生初デプロイ!

アプリケーションの名前を変更する。

$ heroku rename アプリケーション名

1章はここまで。
開発環境を作って、コマンドの説明があって、Gitの解説があり、デプロイを行い本番に反映するまで行うとは1章なのに盛りだくさんですごい。
わからない単語祭りで頭パンパンになっても焦らずに完走を目指したいと思います。
(場合によっては「わからん!スルーだ!」の精神で)

2章へ続く