LoginSignup
0
1

More than 5 years have passed since last update.

ruby on railsのチュートリアルをやってみる

Posted at

はじめに

とある事情によりruby on railsでアプリ開発することになったのでとりあえずチュートリアルやってみる。
今回やってみるチュートリアルはこちら:point_down:
https://guides.rubyonrails.org/getting_started.html
ruby on railsの公式ガイド(だと思う)です。

おそらく日本語訳とかそういうのはありふれてると思うので、rubyすら知らない段階から初めてつまづいたところや分かりにくかったところを残しておこうと思います。

チュートリアルを進める

私がチュートリアルを始めたときの環境は以下です。
ここからrailsに必要なものを入れ始めました。

  • Mac OS Mojave
  • fish 2.7.1
  • anyenv + ndenv (普段Node.js触ってるから)
  • ruby (v2.3のどれか…忘れました。Mac買った最初から入ってたバージョンのまま一切触ってない。)

3. Creating a New Rails Project

チュートリアルに従うと、まずはrubyのバージョンを確認してrailsをインストールする…のですが。
「anyenv入れてるしrbenvとかあるらしいしrubyのバージョン管理はrbenvでしたほうが良いんじゃね?」
という謎の思いつきによりrbenvを導入。fish環境でanyenvを使うという本筋と違うところで時間食ったけどなんとか成功。
この部分は別途記事書いてもいいかも。
(fish anyenvとかでググるとよく出てくる「手動でスクリプト書き換える」がやりたくなくて頑張った。)

このあとは手順通りやれば特に難しいところもなし。
…のはずだった。

実行したコマンド
# 3.1 Installing Rails
$ ruby -v # rubyのバージョン確認
$ sqlite3 --version # sqlite3も必要なのでバージョン確認 (このマシンでは最初から入ってた)
$ gem install rails
$ rails --version # railsがインストールされていることを確認

# 3.2 Creating the Blog Application
$ rails new blog # 新しく "blog"という名前のプロジェクトを作成
$ cd blog

4. Hello, Rails!

4.1 Starting up the Web Server

チュートリアルで毎度おなじみのHello Worldですね。
とりあえずサーバを起動します。

実行したコマンド
$ bin/rails server
Could not find public_suffix-3.0.3 in any of the sources
Run `bundle install` to install missing gems.

はい、コケました。チュートリアル通りやったやん!:cry:
エラーメッセージをよく見ると、bundle installしてねって書いてあるのでやってみます。

実行したコマンド
$ bundle install  # 不足しているgemをインストールしてくれるらしい(?)
$ bin/rails server # 今度は起動した!

bundle installなんてチュートリアルになかった…なんて思って見直してみると、3.2節の説明にちょこっと書いてました。ショック。
たぶんruby触ってる人に取ってはこれくらいは常識なのでしょう。

あと気になったのは、railsコマンドをgemでインストールしたはずなのに、bin/railsからサーバ起動させてるところ。
これはきっとnode.jsで言うところのnpm install --globalで入れたコマンドがプロジェクトごとにバージョン違って困っちゃう問題と同じ意味合いなのだろう。

これと関連して、gem installでインストールするgemはrubyのバイナリと紐付いているようなので、rbenvでrubyのバージョン変えると「そんなgemはこのバージョンにはねぇ!」って怒られた。
gemをプロジェクトごとに管理することってできないのだろうか。
知ってる人教えてください。

4.2 Say "Hello", Rails

ここまでだとデフォルトのページが表示されただけなので、ちゃんと"Hello, Rails!"って出しましょう。

実行したコマンド
$ bin/rails generate controller Welcome index

これで新しくControllerというものを作った…らしい。
機能単位で分けたページ群というぐらいのくくりだろうか。
Welcomeコントローラのviewを編集するだけで特に難しいところもなし。

4.3 Setting the Application Home Page

サーバーのルートにアクセスしたときにHello, Railsが表示されるようにしてみましょう、ということらしい。

チュートリアルに従ってconfig/routes.rbを編集してみる。

config/routes.rb
Rails.application.routes.draw do
  get 'welcome/index'

  root 'welcome#index'
end

これで以下の2つのルートが設定された。

  • localhost:3000にアクセスしたらHello,Railsが表示されるようになった。
  • localhost:3000/welcome/indexにアクセスしてもHello,Railsが表示されるようになった。

ここで2つ疑問。
1つ目は、一番最初に表示されていたページはどこにアクセスしても見られなくなった。
初期プロジェクトのどのファイルが初期ページと紐付いていたのでしょう…?

2つ目は、routes.rbgetrootでパスの表記が違うこと。
生成されたcontrollers/welcome_controller.rbdef indexという記述があるので、どちらもこいつの指定だと思うのだけれど…。

とりあえず疑問を残したまま次へ進む。

5. Getting Up and Running

次はリソース(?)を追加する。

config/routes.rb
Rails.application.routes.draw do
  get 'welcome/index'

  resources :articles # ここを追加した

  root 'welcome#index'
end

なんとこれだけでlocalhost:3000/articles周りのREST Interfaceが用意されるらしい。(もちろん中身を実装しないとアクセスしてもエラーだけど)
なんて楽な。

さらに、今どんなルートが設定されているかも見れるらしい。

ルート確認
$ bin/rails routes

普段Node.js+expressでサーバ組んでる私にとっては結構衝撃的である。いつもルートが訳わからなくなるんだよねー。こりゃ便利。

5.1 Laying down the groundwork

articlesの中身を実装していくらしい。

実行したコマンド
$ bin/rails generate controller Articles

そういえばWelcome controllerを作ったときより引数が一つ少ない。
この場合、viewには何も生成されなくて、controllerの中身も空らしい。なるほど。

チュートリアルに従うと、まずはControllerに実装したいパス(今回は/articles/new)を定義して。

app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
  def new
  end
end

次に、そのパスにアクセスされたときに表示するviewを作る。

app/views/articles/new.html.erb(新規作成)
<h1>New Article</h1>

すると、エラーなく表示されるようになる。ふむふむ。

5.2 The first form

railsでフォームを扱うときにはform_withというヘルパーメソッドが使えるらしい。
チュートリアルのものをそのまま使う。

app/views/articles/new.html.erb
<h1>New Article</h1>

<%= form_with scope: :article, local: true do |form| %>
  <p>
    <%= form.label :title %><br>
    <%= form.text_field :title %>
  </p>

  <p>
    <%= form.label :text %><br>
    <%= form.text_area :text %>
  </p>

  <p>
    <%= form.submit %>
  </p>
<% end %>

これでタイトルとテキストを入力するフォームと、submitボタンが配置された。
おもむろに適当なテキストを入力してsubmitすると、No route matches [POST] "/articles/new"だそうだ。
確かに、ブラウザからアクセスした(GETリクエスト)ときに表示させるページは作成したが、POSTしたときの動きは実装していない。

ただ、RESTの考えから行くと、ここでPOSTしてほしいのは/articles/newではなく/articlesのはずだ。
なぜならPOSTして作って欲しいオブジェクトはarticleであってnewではない。

というところの解決策が次に書いてあった。
どうやらurl:というオプションを使うらしい。

app/views/articles/new.html.erb(抜粋)
<%= form_with scope: :article, url: articles_path, local: true do |form| %>

このarticles_pathというのがどこから来たのか気にはなるが、きっとconfig/routes.rbに書いたresourcesあたりと紐付いているのだろう。

5.3 Creating articles

次にやるのは/articlesにPOSTしたときの動作を実装すること。
まずはControllerにパスを登録する。

app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
  def new
  end

  def create
  end
end

パスを登録する、と言ったが、def createとなっているあたりどうも違うらしい。
ここではあくまでこのControllerが扱う動作を定義しているだけで、ここで定義した動作とサーバのパスをマッピングするのはconfig/routes.rbなのだろう。

次に、createで行う動作を記述する。

app/controllers/articles_controller.rb(抜粋)
def create
    render plain: params[:article].inspect
end

renderメソッドで行えるのは単純に画面にデータを貼り付けることらしい。なるほど。

5.4 Creating the Article model

ここまで散々articleというものが出てきたが、そういえばそのデータモデルは何も作っていない。
ここでやっと作るらしい。

実行したコマンド
$ bin/rails generate model Article title:string text:text

ここで、実行すると何やらdbというディレクトリの中にファイルが生まれたことに気づく。
どうやらrailsではアプリの中にDBまで含んであるようだ。ほほう。

5.5 Running a Migration

5.4が終わった段階で/articles/newにアクセスすると、何やらMigration Errorというものが出てきた。
データモデルを変更したときは、DBのマイグレーションをしなければならないようだ。

実行したコマンド
$ bin/rails db:migrate

どうやらこのコマンドを実行することで、アプリに組み込んであるDBのテーブル構造を新しいものにマイグレーションするらしい。
自分でSQL書いてゴニョゴニョする必要がないのは確かに楽だと思う。

チュートリアルにも強調してあるが、上のコマンドでマイグレーションが実行されるのはあくまでdevelopment環境だけだそうだ。
production環境もマイグレーションする場合、RAILS_ENV=productionというオプションを付ける必要があるらしい。

5.6 Saving data in the controller

データモデルを作成したので、/articles/newで表示するフォームから送信したデータを保存するように修正する。

app/controllers/articles_controller.rb(抜粋)
def create
  @article = Article.new(params[:article])

  @article.save
  redirect_to @article
end

修正して実行したら通る…と思いきや。ForbiddenAttributesErrorだそうな。
どうやらrailsが持つstrong_parametersと呼ばれる機構で保護されているらしい。

これの許可を取るために下のようにも書けるそうな。

app/controllers/articles_controller.rb(抜粋)
@article = Article.new(params.require(:article).permit(:title, :text))

ただ、操作ごとに毎回書くのも汚いし良くない、ということで次のようにprivateにしてやる方が良いらしい。

app/controllers/articles_controller.rb(抜粋)
def create
  @article = Article.new(article_params)

  @article.save
  redirect_to @article
end

private
  def article_params
    params.require(:article).permit(:title, :text)
  end

5.7 Showing Articles

前節でcreateしたときの動作を定義したが、よく見ると"記事を保存したあと、その記事自体にリダイレクトする"という動作になっている。
そのため、今度は/articles/:idへのGETリクエストを処理する部分を実装しなければならない。

app/controllers/articles_controller.rb(抜粋)
def show
    @article = Article.find(params[:id])
end

:idというのは、bin/rails routesで確認できるパスのうち、/:idとなっている部分と紐づくらしい。

ここではredirectrenderをしていないので、viewを用意してやる必要がある。

app/views/articles/show.html.erb(新規作成)
<p>
  <strong>Title:</strong>
  <%= @article.title %>
</p>

<p>
  <strong>Text:</strong>
  <%= @article.text %>
</p>

ここまで来ると、記事登録画面→API経由で記事を登録→登録した記事を表示、までできるようになる。

5.8 Listing all articles

続きは時間のあるときにやります…。

まとめ

ちゃんと覚えればWebサービスをサクッと立ち上げたいときにはすごく楽かもしれない。
外部のサービスと連携したいときは?とか、まだ気になるところはたくさんあるけれども。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1