Skip to content

Instantly share code, notes, and snippets.

@peketamin
Last active August 27, 2018 01:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save peketamin/dbd2b2ba707a66ccc9d06fb703c3c609 to your computer and use it in GitHub Desktop.
Save peketamin/dbd2b2ba707a66ccc9d06fb703c3c609 to your computer and use it in GitHub Desktop.
ログ: Rails Girls のチュートリアルをやる

ログ: Rails 入門をやる

Updated: 2018/08/25

開発環境

  • OS: macOS
  • Ruby environment manager: rvenv
  • Ruby version: 2.5.0
  • Editor: VS Code

2度目のチャレンジ

Rails は昔 「10分で作るRailsアプリ for Windows」 http://masuidrive.jp/rails/ を見てちょっとだけかじったことある。 ただ、動画をなぞりながらも、自分がなにをやっているか理解できず、 scaffold が出来たところで挫折。

当時は、Webフレームワークが普及し始めの頃で、MVCも見慣れてなかったし、オブジェクト指向もよくわかってなかった (※ いまだにわかってない)。 Rails台頭以前、アーキテクチャ模索中Webフレームワークはちょこちょこあったけど、キラーアプリと言えるほどの完成度のものはなく、OSSのよくわからんものを頑張って覚えて、不具合があればモンキーパッチ当てながら使うぐらいなら、独自に自作した方が良いし、そういうものだろう、といった認識が各社にあったように思う。 ORMに関しても、ORMというよりはDAOというものを作ってやっていたように思う。

さておき、13年ぶり2度目の Rails 入門チャレンジとなる。 今日は会社の日帰りエンジニア合宿で、 Ruby を業務で使っている参加者も多く、困ったら聞ける人が近くにいる良い機会である。

以前、 Atom で開発環境を構築しようとしたのだが、補完支援する rsense のインストールがうまくできず、またもや挫折したのだった。 今回はそれを踏まえ、デフォルトでもある程度コーディング支援してくれる IDE として Visual Studio Code を選択した。

Ruby 自体の知識を仕入れるために、「プロを目指す人のためのRuby入門」をザーッと流し読みした (後半はちゃんと理解できてない)。

開発用サーバーを立ち上げるまで

Rails Girls インストール・レシピ (http://railsgirls.jp/install) を参考にして進めていく。

Docker は使わず、まずは、ローカルに直接環境を作っていく。 rbenv は他の作業で使っているのでセットアップ済み。

$ gem install rails

ここから Rails ありきの作業。サンプルとして book モデルを作り、開発用Webサーバーで Rails が正常にセットアップできているか確認する。

$ rails new rails_tutorial
$ cd rails_tutorial
$ rails s
  • rails s で開発用サーバーが立ち上がる。

ブラウザで http://localhost:3000/ にアクセすると、無事 "Yay! You’re on Rails!" が表示された。

これで Rails アプリを作る作業場が出来た。

サンプルアプリを作る

Rails Girls アプリ・チュートリアル (http://railsgirls.jp/app) を参考に進めていく。

その前に、どんなファイルが作られていったかがわかるように git 管理する。

rails_tutorial ディレクトリを見ると、 rails プロジェクト作成後は自動的に git init はされているようだ。

2018-08-25 12:57:40|rails_tutorial|yuki.yokoyama$ ls -a
./             .git/          .ruby-version  Gemfile.lock   Rakefile       bin/           config.ru      lib/           package.json   storage/       tmp/
../            .gitignore     Gemfile        README.md      app/           config/        db/            log/           public/        test/          vendor/

デフォルトファイルやよくあるファイルタイプを add しないように https://github.com/github/gitignore/blob/master/Rails.gitignore から Rails 用の内容を取ってきて、今の .gitignore とマージする。

下記エントリだけは残す。

# Ignore all logfiles and tempfiles.
/log/*
/tmp/*
!/log/.keep
!/tmp/.keep
 
# Ignore uploaded files in development
/storage/*
!/storage/.keep

重複する設定を github からコピーしてきた内容から削除する。下記箇所。

/log
/tmp

/db/*.sqlite3
/db/*.sqlite3-journal  

この状態で、 git commit -a -m 'initial' しておく。

ここから、 scaffold を使っていく。

$ rails generate scaffold idea name:string description:text picture:string
$ rails db:create
$ rails db:migrate
  • rails g scaffold <モデル名> でモデルが作れる。
    • Django だと app_name/models.py をゴリゴリ自分で書いていくところが、 Rails だとコマンドラインでモデル定義のスケルトンを作ってくれる。
    • モデル名以降は、フィールド名とその型定義をスペースで並べていく
    • rails destroy scaffold MyFoo で scaffold で作ったモデルが削除できるようだ (link)
  • rails db:create で DB が作られ、 rails db:migrate でモデル定義が DB にマイグレーションされる。

ここでトラブル。

rails generate を入力後、先に進まない。 http://app.road.jp.net/?p=1679 を読むと、

  • spring stop
  • bin/spring

で spring とやらを再起動してやるとよいようだ。 Spring は Ruby アプリケーションのプリローダーらしい。さすが Rails 、重厚感ある。

spring の再起動後は無事、 rails generate が通った。

この段階で追加されたファイルたちは下記。

2018-08-25 14:41:10|rails_tutorial|yuki.yokoyama$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   config/routes.rb

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	app/assets/javascripts/ideas.coffee
	app/assets/stylesheets/ideas.scss
	app/assets/stylesheets/scaffolds.scss
	app/controllers/ideas_controller.rb
	app/helpers/ideas_helper.rb
	app/models/idea.rb
	app/views/ideas/
	db/migrate/
	db/schema.rb
	test/controllers/ideas_controller_test.rb
	test/fixtures/ideas.yml
	test/models/idea_test.rb
	test/system/ideas_test.rb

それぞれ中身を確認していくこと。

アプリケーションを整えていく

http://railsgirls.jp/app を続ける。

HTML や CSS に手を加え、 http://localhost:3000/ideas にアクセスすると、CRUD 用の画面が出来上がっている。

写真のアップロード

Gemfile に gem 'carrierwave' を加えろとのこと。

Django だと、ファイルアップロード用のモデルクラスがあらかじめあるのでそれを使うが、 Rails では特にデフォルトのものはないらしい。

Gemfile に追加後、 bundle コマンドを実行。

$ bundle

bundle install とか、 bundle exec ~~ とかしか使ったことなかったので、 bundle とだけ打ち込んだ場合の挙動がよくわからない。 多分、 Gemfile に書かれたライブラリを良い感じに組み込んでくれるのだと思う。 (あとで調べたところ、 bundlebundle install と同じ動きになるようだ)

rails generate uploader Picture を実行。これは先ほどのライブラリ carrierwave をインストールすることにより可能になったことなのだろうか。わからない。

2018-08-25 15:18:40|rails_tutorial|yuki.yokoyama$ rails generate uploader Picture
Running via Spring preloader in process 54445
      create  app/uploaders/picture_uploader.rb

app/uploaders/picture_uploader.rb にファイルが作られたようだ。

次に、フォーム HTML を編集して、ファイルアップロード用のフォームボタンを作る。

app/views/ideas/_form.html.erb

<%= form.text_field :picture %>

<%= form.file_field :picture, id: :idea_picture %>

に変える。ポイントは下記であろう。

  • form.file_field: フォームのtypeを変えていると思われる。
  • :picture: idea.picture を意味すると思われる。

:pictureidea.picture が呼び出せるのは、 viewファイル冒頭に <%= form_with(model: idea, local: true) do |form| %> と書いてあるからだと解釈した。

なお、 erb でのコメントは <%# %> でできるようだ。 (Django template でいう {# #})

ORMオブジェクトのフィールド定義はどこに書いてあるのか

Django だと models.py にそのまま書いてある。というか、書かないといけない。

Yuuki Yokoyama [15:32] Rails 初心者です。 http://railsgirls.jp/app を見ながら Rails アプリの作り方を学んでいます。 質問です。

$ rails generate scaffold idea name:string description:text picture:string```

で作られたであろうモデルファイル models/idea.rb の内容が

class Idea < ApplicationRecord
end

しかありません。 view ファイルをいじるときに、ideaモデルのオブジェクトにどんなフィールドが生えているか (idea.name とか) を知っておく必要があると思うのですが、どうやって確認するのでしょうか? (Django だと models.py のモデル定義クラスには、生えているフィールド全てが明示的に記述されているので、それを見ればわかる) (edited)

atsuo.shiraki [16:08] db/schema.rbですね

erb の記法について

  • <%= ... %>: PHPで言う所の <?= 'Hello'; ?> と同じ。 <% puts 'Hello' %>
  • <% ... %>: 任意のコードがかける
    • だからといって <% puts 'Hello' %> では文字列出力できない。
    • <% concat 'Hello' %> なら出る。

URL ルーティング

Django で言う所の urls.py。

config/routes.rb に記述する。

ここまででコミットしておく。

$ git add .
# アップロードした写真まで stage に入っているので外す
$ git reset -- public/uploads/idea/picture/3/IMG_2877.PNG
$ touch public/uploads/.gitkeep
$ git add public/uploads/.gitkeep

.gitignore に追加。

# Uploads
public/uploads/
!public/uploads/.gitkeep

コミット。

$ git commit -m 'add idea'
# コミットログを見返してみる
$ git log --stat

サイト情報表示用のコントローラーとアクションの追加

$ rails generate controller pages info

で Pages コントローラーと、その中に info アクションが作られ、それに付随して下記のファイルに変更・追加が入る。

2018-08-25 16:24:52|rails_tutorial|yuki.yokoyama$ git stash pop
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   config/routes.rb

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	app/assets/javascripts/pages.coffee
	app/assets/stylesheets/pages.scss
	app/controllers/pages_controller.rb
	app/helpers/pages_helper.rb
	app/views/pages/
	test/controllers/pages_controller_test.rb

app/views/pages/info.html.erb に変更を加え、 /pages/info にアクセスすると、変更した内容が見えた。 /app/views/layouts/application.html.erb を編集してナビゲーションバーにここへのメニューを追加する。

一旦、すでに追加してあるメニューをコピーして、テキストを書き換えるだけに止める。

<li class="active"><a href="/ideas">Ideas</a></li>
<li class="active"><a href="/pages/info">Pages/info</a></li>

OK。メニューから Pages#info アクションのページにアクセスできた。

ナビゲーションのアクティブ・非アクティブの制御を入れる

何か一つ自分なりの工夫を加えようと思う。現在表示中のページに応じて、ナビゲーションメニューの該当箇所がアクティブであることがわかるよう見た目を切り替えたい。

参考:

current_page?()link_to() を使って、ナビゲーションリンクを作る。

diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index ba29102..57af5a0 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -27,7 +27,8 @@
 
       <div class="collapse navbar-collapse">
         <ul class="nav navbar-nav">
-          <li class="active"><a href="/ideas">Ideas</a></li>
+          <li class="<%= 'active' if current_page?(controller: 'ideas') %>"><%= link_to "Ideas", controller: "ideas" %></li>
+          <li class="<%= 'active' if current_page?(controller: 'pages', action: 'info') %>"><%= link_to "Pages info", controller: "pages", action: "info" %></li>
         </ul>
       </div>
     </div>

おわりに

Rails Girls のおかげでアプリケーション作成の初歩の初歩は大体わかった気がする。

次は公式のチュートリアルをやりたい。

そういえば、 Django のようにテンプレートの継承は出来ないのだろうか。

公式チュートリアル 第2章 Toyアプリケーション (https://railstutorial.jp/chapters/toy_app?version=5.1#cha-a_toy_app) から先のコンテンツは、 Rails のみならず、 Web 開発に必要な知識や知見が散りばめられているのでよさそうな雰囲気。

公式チュートリアルでは、

  • モデル同士のリレーション
  • バリデーションとエラー
  • SCSS による CSS の記述
  • テスト

などについて学べるようだ。

それが終わったら、 $ rails new todo_sample --webpack=vue で、 Vue.js を使ったサンプルアプリ作成も試して見たい。 https://qiita.com/naoki85/items/51a8b0f2cbf949d08b11 (会社の人の話では、この機能はそこまで production ready ではないらしいが)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment