Railsチュートリアルの学習記録 ~1章・2章 scaffold活用~

はじめに

Railsチュートリアルの学習記録です。

第1章 ゼロからデプロイまで

RESTやMVCモデルなど設計思想についても触れられていて、Progateでは省かれている部分もしっかり勉強できますね◎

🙄個人的にVSCodeで開発したいのでcloud9を使うかは悩みどころ。

①バージョン指定してプロジェクト作成

rails _5.1.6_ new hello_app

※bundle iは自動で行われる。Gemfile(gem)の内容をBundlerで実行する。

②hello worldしてみる

application_controller.rbにhelloアクションを記載

class ApplicationController < ActionController::Base
  def hello 
    render html: "hello, world"
  end
end

routes.rbにルートルーティングを設定

Rails.application.routes.draw do
  root "application#hello"
end

rails sして確認

③git活用

リポジトリを作成したうえでプッシュ。

git init
git add .
git commit -m"first"
git remote add origin https://github.com/chobi1125/rails-tutorial.git
git push -u origin master

🙄git addは新しいファイルを作成した際、バージョン管理下に置く役割で使用。

ためしにroutes.rbを削除。

現在の状態を確認するとroutes.rbがdeletedになっているのを確認。

> git status
On branch master
Your branch is up to date with 'origin/master'.

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        deleted:    config/routes.rb

no changes added to commit (use "git add" and/or "git commit -a")

以前のコミット時の状態に戻したい場合はcheckoutコマンド。

> git checkout -f // fオプションで強制的に以前の状態に上書き
> git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

🙄誤って削除してしまった際の処置はあまりしたことなかったので参考になります。

ブランチ作成

> git checkout -b dev
> git branch
* dev
  master

※適当にテストファイルなりで編集する。

マージ

> git checkout master
> git merge dev

🙄再度前述の方法でpushした場合、リモートリポジトリにはmasterブランチしかないのがミソですね。devブランチはローカルにしかありません。

④Herokuへのデプロイ

Gemfileに本番環境の設定を追記

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

sqlite3が本番環境に導入されないように明記

group :development, :test do
  gem 'sqlite3', '1.3.13'
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

本番用のgemをローカルの環境にインストールしないよう注意してインストール

bundle install --without production

※僕の場合エラー

Bundler could not find compatible versions for gem "ruby ":
  In Gemfile:
    ruby  (~> 2.6.6.0) x64-mingw32

    pg (= 0.20.0) x64-mingw32 was resolved to 0.20.0, which depends on
      ruby  (>= 2.0, < 2.5) x64-mingw32

🙄どうやらpostgreSQLとコンフリクトしてるみたいですね。

pgのバージョンを固定しないように編集して再実行で成功しました。

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

herokuがインストール済みか確認

> heroku --version
» Warning: heroku update available from 7.35.0 to 7.38.1.
heroku/7.35.0 win32-x64 node-v12.13.0

ログインしてSSHキーを追加

heroku login --interactive
heroku keys:add

アプリの実行場所を作成

heroku create
Creating app... done, fathomless-beyond-39164
https://damp-fortress-5769.herokuapp.com/ |
https://git.heroku.com/damp-fortress-5769.git

※URLはいったんRailsチュートリアルのコピペ

デプロイ

git push heroku master

🙄gitを使ってリポジトリをプッシュするんですね~

ここでエラー

In Gemfile:
remote: sqlite3
remote:
remote: !
remote: ! Failed to install gems via Bundler.
remote: ! Detected sqlite3 gem which is not supported on Heroku:
remote: ! https://devcenter.heroku.com/articles/sqlite3
remote: !
remote: ! Push rejected, failed to compile Ruby app.

事前にリポジトリにGemfileの変更をpushしていなかったからかもしれません。。。

再度リモートリポジトリを更新してからherokuにpush

git add .
git commit -m"gemfile edit"
git push
git push heroku master
heroku open // 起動

成功しました。

アプリ名を試しに変える。

> heroku rename rails-tutorial-hello1125
Renaming majestic-redwood-19086 to rails-tutorial-hello1125... done
https://rails-tutorial-hello1125.herokuapp.com/ | https://git.heroku.com/rails-tutorial-hello1125.git
Git remote heroku updated
 !    Don't forget to update git remotes for all other local checkouts of the app.

🙄ドメイン名をめちゃくちゃ簡単に変更することができました。

第2章Toyアプリケーション

リンク

※僕はいろいろエラーにつまずきまして2回プロジェクトを作成しなおしました。また、この章ではエラー回避のためGitやGemfileの更新はしませんでした。

1回目:1章のプロジェクトを流用してscaffoldジェネレータを使ったところ、エラーになったので1から作り直し。プロジェクトをそもそもバージョン指定せずに作成していたのも原因ぽい。

2回目:マイグレートができなくなる。おそらくgemfile更新後にwithout productionコマンドを含めずインストールしてしまったため。

3回目:Gemfileを弄らず、Gitへのpushも行わずに試しました。

①バージョン指定してプロジェクト作成

rails _5.1.6_ new scaffold

②Rails標準装備のscaffoldジェネレータを使う

rails generate scaffold User name:string email:string

マイグレート

rails db:migrate

http://localhost:3000/usersへアクセスして確認

新規登録するとこうなる。すでにCRUD実装されています◎

routes.rbの確認

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

※:usersという一見奇妙な記法は、Ruby言語特有の「シンボル」と呼ばれるもの

🙄ルーティングのresourcesは初めて見ましたね!LaravelでいうRoute::resourceですね!!FWではRESTful設計が簡単にできるよう何かしら用意されていますね!!

users_controller.rbの確認

class UsersController < ApplicationController
  before_action :set_user, only: [:show, :edit, :update, :destroy]

  def index
    @users = User.all
  end

  def show
  end

  def new
    @user = User.new
  end

  def edit
  end

  def create
    @user = User.new(user_params)
    respond_to do |format|
      if @user.save
        format.html { redirect_to @user, notice: 'User was successfully created.' }
        format.json { render :show, status: :created, location: @user }
      else
        format.html { render :new }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end

  def update
    respond_to do |format|
      if @user.update(user_params)
        format.html { redirect_to @user, notice: 'User was successfully updated.' }
        format.json { render :show, status: :ok, location: @user }
      else
        format.html { render :edit }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @user.destroy
    respond_to do |format|
      format.html { redirect_to users_url, notice: 'User was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    def set_user
      @user = User.find(params[:id])
    end
    def user_params
      params.require(:user).permit(:name, :email)
    end
end

🙄長いですがRESTアーキテクチャを構成するすべてのアクションの一覧なのでコピペしました。

以下indexアクションを抜粋。

def index
  @users = User.all
end

user.rbを確認。ApplicationRecordを継承。

class User < ApplicationRecord
end

Active RecordというRubyライブラリを継承しているおかげで、これだけでDB上のすべてのユーザーを返すことができている。

※参考までにapplication_record.rbを確認。

class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true
end
③Scaffoldの欠点

・データ検証(=バリデーション)が行われていない。
・認証機能がない
・テストが書かれていない

④投稿機能

Micropostリソースをscaffoldを用いて作成。

rails generate scaffold Micropost content:text user_id:integer
rails db:migrate

http://localhost:3000/microposts/newへアクセス。

🙄Userリソースとは異なる項目で登録できるようになってますね!すごい。

micropost.rbを編集してバリデーションを加える。

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

確認すると実装できていますね!

データのリレーション(関連付け)をする

models/user.rb

class User < ApplicationRecord
  has_many :microposts
end

models/micropost.rb

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

上記でマイクロポストとユーザーが関連付けされる。

確認

rails c
> user = User.first
> user.microposts
  Micropost Load (0.2ms)  SELECT  "microposts".* FROM "microposts" WHERE "microposts"."user_id" = ? LIMIT ?  [["user_id", 2], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Micropost id: 2, content: "test2", user_id: 2, created_at: "2020-07-05 04:41:17", updated_at: "2020-07-05 04:41:17">]>

# ここまででUser側からmicropostsにアクセスできることを確認

> micropost = User.first.microposts.first
=> #<Micropost id: 2, content: "test2", user_id: 2, created_at: "2020-07-05 04:41:17", updated_at: "2020-07-05 04:41:17">
> micropost.user
=> #<User id: 2, name: "sato", email: "sato@example.com", created_at: "2020-07-05 04:38:42", updated_at: "2020-07-05 04:38:42">

# これでmicropostsからuserデータを取得できることを確認

最後にバリデーションを追加。

models/micropost.rb

class Micropost < ApplicationRecord
  belongs_to :user
  validates :content, length: { maximum: 140}, presence: true
end

models/user.rb

class User < ApplicationRecord
  has_many :microposts
  validates :name, presence: true
  validates :email, presence: true
end

🙄Progateではリレーションについて触れられていなかったので参考になる!!

※この後にあるデプロイはいったん割愛します。

躓いた点

✅SQLiteのエラー

cannot load such file -- sqlite3/sqlite3_native (LoadError)

参考:WindowsでRailsTutorialするときに気をつけること

※ターミナルが長文なので平文で記載しています。

サーバ起動すると以下のようなエラーが。

C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/sqlite3-1.3.13-x64-mingw32/lib/sqlite3.rb:6:in `require’: cannot load such file — sqlite3/sqlite3_native (LoadError)

コマンド実行でsoファイル作成

gem install sqlite3 –platform=ruby — –with-sqlite3-include=C:/sqlite-amalgamation-3230100 –with-sqlite3-lib=C:\Ruby26-x64\bin

以下のフォルダからsoファイルをコピー

“C:\Ruby26-x64\lib\ruby\gems\2.6.0\gems\sqlite3-1.4.2\lib\sqlite3\sqlite3_native.so”

下記にペーストする。
※sqlite3-1.3.13-x64-mingw32がインストールされている場合、こちら優先のため

C:\Ruby26-x64\lib\ruby\gems\2.6.0\gems\sqlite3-1.3.13-x64-mingw32\lib\sqlite3

サーバー起動できました◎

✅バージョン指定のし忘れでサーバー起動できない

・`load_defaults’: Unknown version “5.2” (RuntimeError)

これはrails newの際にバージョンしていなかった場合に起こる。

参考:Rails Aborted! Unknown Verison 5.2と出たら

🙄上述のようにプロジェクトを1から作り直した方がよさそう。。。いったんプロジェクト再作成で回避します。

✅マイグレートできない

マイグレートがエラー

> rails db:migrate
rails aborted!
bin/rails:4:in `require'
bin/rails:4:in `<main>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)

こうなる

下記コマンドを試すもrailsコマンドが実行できないとエラーになる。

bin/rails db:migrate RAILS_ENV=development

🙄gemのインストールで本番、開発環境がごっちゃになってしまったからだと思われます。解消法もあると思いますが、いったんプロジェクトを再作成で回避します。

おわりに

今までLaravelなどでデプロイ経験していたからHerokuへのデプロイまえにリモートリポジトリを最新状態に更新しておくなどの対処ができた気がします。

地味にハマりどころあるなといった印象。。。確かに初学者だとつらい気が。

また、WindowsローカルでRailsやっていて、環境を汚している感が気になり始めました。。。

404エラーなども早く実装してみたいな~。

✅その他参考

bundle install と bundle updateの違いについて

bundle i はgemfile.lockを元にインストール

bundle updateはgemfileを元にインストールしgemfile.lockを更新する。

REST入門 基礎知識

【初級編】直前にコミットしたメッセージを変更する

git commit --amend -m "gemfile編集してherokuデプロイまで。1章終了"

上記で直前のコミットのコメントを変更できる

git log --oneline
b7caa0a (HEAD -> master) gemfile編集してherokuデプロイまで。1章終了
5854f05 (dev) README Edit
e08c71f first

備忘録

✅scaffoldジェネレータで作成されるもの一覧。

> rails generate scaffold User name:string email:string
invoke active_record
create db/migrate/20200705025641_create_users.rb
create app/models/user.rb
invoke test_unit
create test/models/user_test.rb
create test/fixtures/users.yml
invoke resource_route
route resources :users
invoke scaffold_controller
create app/controllers/users_controller.rb
invoke erb
create app/views/users
create app/views/users/index.html.erb
create app/views/users/index.html.erb
create app/views/users/edit.html.erb
create app/views/users/show.html.erb
create app/views/users/new.html.erb
create app/views/users/_form.html.erb
invoke test_unit
create test/controllers/users_controller_test.rb
create app/helpers/users_helper.rb
invoke test_unit
invoke jbuilder
create app/views/users/index.json.jbuilder
create app/views/users/show.json.jbuilder
create app/views/users/_user.json.jbuilder
invoke test_unit
create test/system/users_test.rb
invoke assets
invoke coffee
create app/assets/javascripts/users.coffee
invoke scss
create app/assets/stylesheets/users.scss
invoke scss
create app/assets/stylesheets/scaffolds.scss

 

 

 

コメントを残す