- 小学生でもわかるRuby on Rails入門に従って、Twitterみたいなサイトを作成してみます。
1 Railsとは
- Webアプリケーションを開発するために設計されたものをWebアプリフレームワークと言います。
- フレームワーク自体はプログラミング言語ではありません。フレームワークはある特定のことに特化した機能を集めたものです。
- 最も先進的で安定しており、豊富なRubyGemsライブラリがあることで他のフレームワークに比べプロトタイプを作るスピードを早めることが可能
2 Railsの導入
- RubyGemsを使ってインストール。
sudo gem install rails
- Xcodeまたはコマンドラインツールに問題がある場合は、下記コマンドで再インストールする。
xcode-select --install
3 Railsアプリの新規作成
- Twitterのようなアプリを soushi-twitter という名前作ることにします。
- 下記コマンドを打つと、自動でRailsアプリのテンプレートが生成されます。
rails new soushi-twitter
cd ~/soushi-twitter
- treeコマンドで自動生成されたファイルを確認します。
tree ~/soushi-twitter
├── Gemfile
├── Gemfile.lock
├── README.rdoc
├── Rakefile
├── app
├── bin
├── config
├── config.ru
├── db
├── lib
├── log
├── public
├── test
├── tmp
└── vendor
4 Railsアプリをカスタマイズする
4.1 モデルー・ビュー・コントローラ(MVCモデル)
- RailsにおけるモデルはPush-MVCと呼ばれるものです。
- これは、ModelとView、両者を知っているのは、Controllerしかいません。よってControllerにがんばってもらおう、という戦略です。
- ViewはControllerがトリガになって更新されるため、受け身です。このことから、このViewのことをPassive Viewと呼んだりします。
- 参考 MVC、本当にわかってますか?
4.2 ビューおよびコントローラーの作成
- コマンド1つで作成できます。
- このindexというのは、ユーザーの一覧ページ。showというのは、ユーザーのプロフィールページです。
- indexやshowは自分で==自由に名前をつけることが可能==ですが、あとで説明するように==index==、==show==というようにつけるのが==良し==とされています。
- また、==コントローラー名は==usersというように==複数形==にするのがよしとされています。
- こういう暗黙の約束事のようなものをRailsの規約と言います。 Railsはその名の通りレールに沿って作ればカンタンに作れる、という意味なので、出来る限りRailsが敷いたレールの上を走りましょう。
rails g controller users index show
- 次のようなファイルが自動生成されます。
app/controllers/users_controller.rb
app/views/users/index.html.erb
app/views/users/show.html.erb
4.3 サーバーの起動
- 実は、ここまででもうWebページが完成しています。
rails s
-
rails s
コマンドでサーバーを起動し、Webブラウザでhttp://0.0.0.0:3000/users/index
にアクセスしてみます。
4.4 ビューのカスタマイズ(1)
-
app/views/users/show.html.erb
を次のように編集します。 -
app/views/users/show.html.erb
<h1>Soushi Yamamoto</h1>
<p>soushiy</p>
<ul>
<li>Location : Tokyo</li>
<li>About : Hello</li>
</ul>
- Webブラウザで
http://0.0.0.0:3000/users/show
にアクセスします。
4.5 ビューのカスタマイズ(2)
- 再度、
app/views/users/show.html.erb
を次のように編集します。 - app/views/users/show.html.erb
<h1><%= @user[:name] %></h1>
<p><%= @user[:username] %></p>
<ul>
<li>Location : <%= @user[:location] %></li>
<li>About : <%= @user[:about] %></li>
</ul>
- 再度、Webブラウザで
http://0.0.0.0:3000/users/show
にアクセスします。 - エラーが発生しています。
-
undefined method '[]' for nil:NilClass
というエラーは、@userから情報を引っ張ろうとしているけど、@userに情報が入っていないということで起こっています。 - そこで、コントローラーで@userに情報を埋め込みます。
4.6 コントローラーのカスタマイズ
- コントローラーを編集して、@userに情報を埋め込みます。
-
app/controllers/users_controller.rb
を次のように変更します。
class UsersController < ApplicationController
def index
end
def show
@user = Hash.new
@user[:name] = 'Soushi Yamamoto'
@user[:username] = 'soushiy'
@user[:location] = 'Tokyo, Japan'
@user[:about] = 'Hello.'
end
end
- 正しく表示できました。
5 ルーチングの設定
5.1 ルーチングの必要性
-
http://0.0.0.0:3000/users/show
にアクセスすると、すべて同じ人のプロフィールになっています。 - これを
http://0.0.0.0:3000/users/show/soushiy
にアクセスすると、soushiy
のプロフィールが表示され、 -
http://0.0.0.0:3000/users/show/tanaka
にアクセスすると、tanaka
のプロフィールがそれぞれ表示されるようにするために、ルーチングという仕組みを使います。
5.2 ルーチングの役割
- ルーチングはユーザーがアクセスしたURLをもとに何を表示するかをすべて振り分けています。
- すなわち、ルーチングの役割は、ユーザーがSoushi Yamamotoを表示しろというURLにアクセスしたら、その情報を表示するようにし、Taro Tanakaを表示しろというURLにアクセスしたら、その情報を表示するようにする、いわば「URLの仕分け」のようなことをしています。
- したがって、実はURLにアクセスした時に最初に通るところがルーチングになるのです。
- ページが表示されるまでの流れは以下のとおり。
ユーザーがURLにアクセス
ルーチングが仕分け
コントローラーが値を入れる
ビューがコントローラーから渡された値を表示
5.3 ルーチングのカスタマイズ
-
http://0.0.0.0:3000/users/show/soushiy
で、プロフィールページを表示したいので、config/routes.rb
を下記のように編集します。 -
config/routes.rb
Rails.application.routes.draw do
get 'users/index'
get 'users/show'
get 'users/show/:username' => 'users#show'
end
- WEBブラウザで
http://0.0.0.0:3000/users/show/soushiy
にアクセスします。
6 ルーチングからコントローラーへ値を渡す
-
ルーチングの値は
params[:username]
で取得可能。 -
これは、先ほど、ルーチングのファイル
config/routes.rb
にget "users/show/:username" => "users#show"
と記述したからである。 -
コントローラーの動作を、ルーチングによって変更するようにします。
-
app/controllers/users_controller.rb
を下記のように変更します。
class UsersController < ApplicationController
def index
end
def show
@user = Hash.new
if params[:username] == 'soushiy'
@user[:name] = 'Soushi Yamamoto'
@user[:username] = 'soushiy'
@user[:location] = 'Tokyo, Japan'
@user[:about] = 'Hello.'
elsif params[:username] == 'tarot'
@user[:name] = 'Taro Tanaka'
@user[:username] = 'tarot'
@user[:location] = 'Yamaguchi, Japan'
@user[:about] = 'I'm Taro.'
end
end
end
- WEBブラウザで
http://0.0.0.0:3000/users/show/soushiy
とhttp://0.0.0.0:3000/users/show/tarot
を開きます。
7. モデルの作成
- Railsにおけるモデルとは、mysqlやHBase(大規模キーバリューストア)等を指す。
- スキーマを直接定義するのではなく、マイグレーションを書く。
7.3.1 データベースの新規作成
- db/development.sqlite3 が作成されます。
- この時点では何もないまっさらなもの(スキーマやマイグレーションファイルも無い)。
rake db:create
7.3.2 モデルの作成
- モデルはusersではなく、userという単数形であることに注意しましょう。これもRailsの敷いたレールの一つです。
カラム名 | 型 | 意味 |
---|---|---|
name | string | 表示名 |
username | string | ユーザー名 |
location | string | 居住地 |
about | text | 自己紹介 |
rails g model user name:string username:string location:string about:text
- 下記は、マイグレーションの型とMySQL、Rubyの型の対応表です。
|マイグレーションの型|MySQLの型|Rubyの型|
|----|----|----|----|
|integer|int(11)|Fixnum|
|decimal|decimal(10,0)|BigDecimal|
|float|float|Float|
|string|varchar(255)|String|
|text|text|String|
|binary|blob|String|
|date|date|Date|
|datetime|datetime|Time|
|timestamp|datetime|Time|
|time|time|Time|
|boolean|tinyint(1)|TrueClass/FalseClass|
- 次のようなファイルが生成されます。
- user.rb・・・モデルファイル
- {日付}_create_users.rb・・・マイグレーションファイル
app/models/user.rb
db/migrate/20150825110207_create_users.rb
cat db/migrate/20150825110207_create_users.rb
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :name
t.string :username
t.string :location
t.text :about
t.timestamps null: false
end
end
end
7.3.3 マイグレーションファイルを用いてデータベースにスキーマを適用
- 下記コマンドで、実際にスキーマが適用されたデータベースとなります。
rake db:migrate
8 データベースにデータを入れる
- ==初期データを入れるためのファイル==
db/seeds.rb
を、下記のように変更します。
@user = User.new
@user.name = 'Soushi Yamamoto'
@user.username = 'soushiy'
@user.location = 'Tokyo, Japan'
@user.about = 'Hello, I am Soushi.'
@user.save
@user = User.new
@user.name = 'Taro Tanaka'
@user.username = 'tarot'
@user.location = 'Yamaguchi, Japan'
@user.about = 'Hi. I am Taro.'
@user.save
- 次のコマンドでデータベースにデータを追加します。
rake db:seed
9 データベースのデータを表示する
- コントローラー
app/controllers/users_controller.rb
を次のように変更します。 - 今回は
User.find_by(:username => params[:username])
となっていますが、User.find_by(:name => 'Soushi Yamamoto')
や、User.find_by(:id => 1)
という検索も可能です。 - idで探す場合は、単純に
User.find(1)
として、idが1のユーザーを取得することもできます。
class UsersController < ApplicationController
def index
end
def show
@user = User.find_by(:username => params[:username])
end
end
- WEBブラウザでそれぞれのページにアクセスします。
10 ツイートを保存するためのビュー・コントローラー・モデルを作成する
- ビューとコントローラーの作成
URL | 意味 |
---|---|
index | タイムラインを表示する |
show | |
new | 新しいツイートを入力する画面 |
rails g controller tweets index show new
- モデルの作成
カラム名 | 型 | 意味 |
---|---|---|
title | string | タイトル |
content | text | 内容 |
rails g model tweet title:string content:text
rake db:migrate
11 ツイートを入力するためのフォームを作る
- 現在、
http://0.0.0.0:3000/tweets/new
の画面は、次のようになっています。
11.1 ビューを修正する
- 新規ツイートを作成するための画面
app/views/tweets/new.html.erb
を、次のように変更します。 - このようなものを==ヘルパー==と言います。 この例の場合は、フォームヘルパーと呼ばれるものです。
<%= form_for Tweet.new do |f| %>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.label :content %>
<%= f.text_area :content %>
<%= f.submit %>
<% end %>
- views/tweetsフォルダが作成されています。
11.2 NoMethodError in Tweets#newエラーに対処する
- ビューを修正した後、再度
http://0.0.0.0:3000/tweets/new
にアクセスすると、エラーが発生しています。
- エラー内容は、==フォームの送信先が存在しない==というものです。
undefined method `tweets_path' for #<#<Class:0x007fe02b2a1918>:0x007fe02b2f8308>
- そこで、ルーチングの設定を書き換えて、送信先を定義してあげます。
-
config/routes.rb
を次のように書き換えます。 - ツイートのフォームを入力して、送信ボタンを押したら、tweetsコントローラーのcreate関数を呼びなさい、という意味です。==(create関数は未定義なので後で作成します。)==
Rails.application.routes.draw do
get 'tweets/index'
get 'tweets/show'
get 'tweets/new'
post 'tweets' => 'tweets#create'
get 'users/index'
get 'users/show/:username' => 'users#show'
end
- 再度、
http://0.0.0.0:3000/tweets/new
にアクセスします。
- ツイートを送信します。(失敗します。)
- tweetsコントローラーに、create関数を追加します。
-
app/controllers/tweets_controller.rb
を次のように変更します。
class TweetsController < ApplicationController
def index
end
def show
end
def new
end
def create
end
end
-
create関数は追加できましたが、何も処理していません。
-
先ほどユーザー名の取得の際に、
params[:username]
としたのと同様に、params[:tweet][:title]
でツイートのタイトルを取得します。 -
以下の様な形で、パラメータが飛んできます。
params = { :tweet => { :title => "This is first tweet title", :content => "I am making how to make twitter app." } }
- そこで、
app/controllers/tweets_controller.rb
を次のように変更します。 -
params[:tweet][:title]
でタイトルの取得 -
params[:tweet][:content]
で内容の取得
class TweetsController < ApplicationController
def index
end
def show
end
def new
end
def create
@tweet = Tweet.new
@tweet.title = params[:tweet][:title]
@tweet.content = params[:tweet][:content]
@tweet.save
end
end
- ここまでで、ツイートの内容は正しく保存されるようになりました。しかし、再度ツイートボタンを押して投稿しようとすると、下記の画面になります。
- これは、==create関数に対応するビューが存在しないため発生するエラーです。==
- createのビューは必要ないので、もしもデータを保存し終わったらツイートの一覧にリダイレクトさせるようにしましょう。
-
app/controllers/tweets_controller.rb
を次のように変更します。
class TweetsController < ApplicationController
def index
end
def show
end
def new
end
def create
@tweet = Tweet.new
@tweet.title = params[:tweet][:title]
@tweet.content = params[:tweet][:content]
@tweet.save
redirect_to '/tweets/index'
end
end
12 ツイートの一覧表示
- ツイートの一覧表示は
tweets#index
を変更すればよいのでした。 - 対応するコントローラー
app/controllers/tweets_controller.rb
を次のように編集します。 -
@tweets = Tweet.all
は、データベースからすべてのデータを取ってくるコマンドです。
class TweetsController < ApplicationController
def index
@tweets = Tweet.all
end
def show
end
def new
end
def create
@tweet = Tweet.new
@tweet.title = params[:tweet][:title]
@tweet.content = params[:tweet][:content]
@tweet.save
redirect_to '/tweets/index'
end
end
- 次に、一覧表示のためのビューを変更します。
- ここで、Rubyのforループのおさらいです。
- 次のようにすると、0〜10までを足した数が表示されます。
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
sum = 0
numbers.each do |number|
sum += number
end
puts sum
- このfor文を用いて、
app/views/tweets/index.html.erb
を次のように編集します。 -
<%
と<%=
の違いに注意します。==イコールの無いものは、HTMLとして表示する必要のないもの==という意味です。
<% @tweets.each do |tweet| %>
<h1><%= tweet.title %></h1>
<p><%= tweet.content %></p>
<% end %>
- 最後に、
http://0.0.0.0:3000/tweets/index
にアクセスします。
この次のステップは?
ここまで学んできて、ある程度Railsの仕組みが理解できたでしょうか?
他にもまだまだやりたいことはたくさんあると思います。
画像をアップロードするためには、どうしたらいいの?
ユーザーのログインをして、ユーザーごとにツイートを表示したい。
実際のTwitterと連動して、ここでつぶやいたことをTwitterにも表示させたい。
などなど。
ここから先は、無限です。
Mitakalabコミュニティで学ぶもよし、本で独学するもよし、Google先生にきくもよし。
自分だけのアプリを作るべくがんばってください。
参考までに、この次のステップで有用なものを挙げておきます。
-
Railscasts : Railsの応用例がたくさん載っているサイトです。(英語・日本語)
-
Cumiki : Railsにかぎらず、Railsの応用例をどうやって付け加えるかを、レゴを組み立てるような手順で学ぶことができます。(日本語)
-
ドットインストール : Railsにかぎらず、基本的な点を動画を使ってわかりやすく解説されています。(日本語)
-
Ruby Toolbox : RailsにGemを追加して機能を付け加えたいときに、どんなGemがあるのかをカテゴリーごとに見ることができます。(英語)