デモアプリケーションをscaffold
ジェネレータですばやく作成
デモアプリの準備
# デモアプリの初期化
$ cd rails_projects
$ rails new demo_app
$ cd demo_app
# Gemfileの書き換え
$ vim Gemfile
Gemfile
source 'https://rubygems.org'
ruby '2.0.0'
#ruby-gemset=railstutorial_rails_4_0
gem 'rails', '4.0.4'
group :development do
gem 'sqlite3', '1.3.8'
end
gem 'sass-rails', '4.0.2'
gem 'uglifier', '2.1.1'
gem 'coffee-rails', '4.0.1'
gem 'jquery-rails', '3.0.4'
gem 'turbolinks', '1.1.1'
gem 'jbuilder', '1.0.2'
group :doc do
gem 'sdoc', '0.3.20', require: false
end
group :production do
gem 'pg', '0.15.1'
gem 'rails_12factor', '0.0.2'
end
# gemのインストール
$ bundle install --without production
$ bundle update
$ bundle install
# gitリポジトリの作成とコミット
$ git init
$ git add .
$ git commit -m "Initial commit"
# GitHubにpush
# 事前にGitHubにdemo_appというリポジトリを作成
$ git remote add origin https://asam-3@github.com/asam-3/demo_app.git
$ git push -u origin master
モデル設計
-
マイクロブログのモデル
- ブログのユーザ
- マイクロポスト
usersデータモデル
列名 | 型 | 備考 |
---|---|---|
id | integer | 一意のキー |
name | string | |
string |
- micropostsデータモデル
列名 | 型 | 備考 |
---|---|---|
id | integer | 一意のキー |
content | string | |
user_id | integer |
Usersリソース
- UsersデータモデルとWebインタフェースが組み合わさったもの
- ユーザをHTTPプロトコル経由で自由に作成/読み出し/更新/削除できるオブジェクト
-
scaffold
ジェネレータでUsersリソースを生成する-
rails generate
スクリプトにscaffold
コマンドを渡す
-
# Usersリソースを作成(Usersデータモデルが作成される)
$ rails generate scaffold User name:string email:string
# データベースをmigrateし、usersデータモデルを作成する
# bundle execを使用するのは、現在のGemfileに対応するバージョンのRakeが確実に実行されるようにするため
$ bundle exec rake db:migrate
# サーバを起動
$ rails s
参考:rakeコマンドについて
- Ruby版のmakeのようなもの
# rakeのデータベースタスクを参照
$ bundle exec rake -T db
rake db:create # Create the database from DATABASE_URL or conf...
rake db:drop # Drops the database using DATABASE_URL or the ...
rake db:fixtures:load # Load fixtures into the current environment's ...
rake db:migrate # Migrate the database (options: VERSION=x, VER...
rake db:migrate:status # Display status of migrations
rake db:rollback # Rolls the schema back to the previous version...
rake db:schema:cache:clear # Clear a db/schema_cache.dump file
rake db:schema:cache:dump # Create a db/schema_cache.dump file
rake db:schema:dump # Create a db/schema.rb file that can be portab...
rake db:schema:load # Load a schema.rb file into the database
rake db:seed # Load the seed data from db/seeds.rb
rake db:setup # Create the database, load the schema, and ini...
rake db:structure:dump # Dump the database structure to db/structure.sql
rake db:version # Retrieves the current schema version number
rake test:all:db # Run tests quickly, but also reset db
# rakeの全てのタスクを参照
$ bundle exec rake -T
(省略)
ユーザページの表示
-
rails generate scaffold User
でUsersリソースを作成すると、ページも自動生成される
URL | アクション | 用途 |
---|---|---|
/users | index | 全てのユーザ一覧を表示 |
/users/1 | show | id=1のユーザを表示 |
/users/new | new | 新規ユーザを作成 |
/users/1/edit | edit | id=1のユーザを編集 |
-
ユーザ関連操作を一通り実施
- 作成
- 表示
- 編集
- 削除
-
RailsにおけるMVCの挙動(/usersにアクセスした際のフロー)
- /usersというURLへのリクエストを発行
- Railsルータが/usersをUsersコントローラ内のindexアクションに割り当てる(ルーティング)
- indexアクションは、Userモデルに「全てのユーザを取得する」と指示する(User.all)
- Userモデルは全てのユーザをDBから取り出す
- Userモデルはユーザの一覧をコントローラに返す
- コントローラはユーザの一覧を@users変数に保存し、indexビューに渡す
- ビューはコードの中に埋め込まれているRubyを使用してHTMLを生成する
- コントローラは生成されたHTMLをブラウザに返す
-
Railsルータのソース
- URLをUsersリソースで使用するコントローラアクションにマッピング
- URLとアクションの組合せを作成
config/routes.rb
DemoApp::Application.routes.draw do
resources :users
end
- scaffoldで生成したコントローラ
- Usersのアクションがまとめられている
app/controllers/users_controller.rb(クラス・メソッド定義のみ)
class UserController < ApplicationController
# 全てのユーザを表示するページ
def index
end
# ユーザを表示するページ
def show
end
# ユーザを新規作成するページ
def new
end
# ユーザを作成するアクション
def create
end
# ユーザを編集するページ
def edit
end
# ユーザを更新するアクション
def update
end
# ユーザを削除
def destroy
end
end
- UsersコントローラとUserモデルの関係を確認
- indexアクション
- Userモデルから全てのユーザの一覧を取り出し、
@users
変数に格納
- Userモデルから全てのユーザの一覧を取り出し、
- indexアクション
app/controllers/users_controller.rb(indexメソッドのみ)
class UserController < ApplicationController
def index
@users = User.all
end
end
- Userモデル
- 継承や
ActiveRecord
ライブラリにより、UserモデルはUser.all
というリクエストに対して全てのユーザを返すことができる
- 継承や
app/models/user.rb(Userモデル)
class User < ActiveRecord::Base
end
- ユーザーのビュー
-
@users
変数に一覧が保存されると、コントローラが下記のビューを呼び出す
-
app/views/users/index.html.erb
<h1>Listing users</h1>
<table>
<tr>
<th>Name</th>
<th>Email</th>
<th></th>
<th></th>
<th></th>
</tr>
<% @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 %>
</table>
<br />
<%= link_to 'New User', new_user_path %>
- Usersリソースの問題
- データのバリデーションチェックが行われていない
- ユーザ認証がない
- テストコードがほぼない
- レイアウトがちょっと
- 理解しにくい
Micropostsリソース
マイクロポストのページを表示
# scaffoldでMicropostを作成
$ rails generate scaffold Micropost content:string user_id:integer
# 新しいデータモデルでDBを更新
$ bundle exec rake db:migrate
-
Micropost
を追加したことによるソースの追加/変更- Railsルータに
Microposts
が追加される -
MicropostsController
など、Usersと同様に各種ファイルの作成
- Railsルータに
- とりあえずマイクロポストをブラウザから2個作ってみる
config/routes.rb
DemoApp::Application.routes.draw do
resources :microposts
resources :users
end
文字数制限の追加
-
validates
を使用して入力制限を追加 - micropostモデルに入力制限のロジックを追加
- 140文字以内
app/models/micropost.rb
class Micropost < ActiveRecord::Base
validates :content, length: { maximum: 140 }
end
UserとMicropostの関連付け
- 一人のユーザに対して複数のマイクロポストを関連付ける
has_many :microposts
- 一つのマイクロポストは一つのユーザにのみ属する
belongs_to :user
app/models/user.rb
class User < ActiveRecord::Base
has_many :microposts
end
app/models/micropost.rb
class Micropost < ActiveRecord::Base
belongs_to :user
validates :content, length: { maximum: 140 }
end
Railsアプリケーションの対話的な操作(rails console
)
- Railsの
console
- Railsアプリケーションを対話的に操作
-
rails console
で起動
-
User
とMicropost
の関連付けを確認
$ rails console
# first_user変数に一人目のユーザを設定
> first_user = User.first
User Load (0.6ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1
=> #<User id: 2, name: "テストユーザー", email: "admin@localhost", created_at: "2014-08-02 06:36:09", updated_at: "2014-08-02 06:36:09">
# ユーザに関連付けられているマイクロポストを参照
> first_user.microposts
Micropost Load (2.4ms) SELECT "microposts".* FROM "microposts" WHERE "microposts"."user_id" = ? [["user_id", 2]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Micropost id: 1, content: "テスト", user_id: 2, created_at: "2014-08-02 06:34:54", updated_at: "2014-08-02 06:35:06">]>
# コンソールを終了
> exit
継承の階層
モデルの継承構造
-
ActiveRecord::Base
クラスを継承- 作成したオブジェクトはDBにアクセスできるようになり、DBのカラムを
Ruby
の属性のように扱えるようになる
- 作成したオブジェクトはDBにアクセスできるようになり、DBのカラムを
コントローラの継承構造
-
ApplicationController
を継承 -
ApplicationController
はActionController::Base
を継承- モデルオブジェクトの操作
- インバウンドHTTP requestのフィルタ
- ビューをHTMLとして出力
- Railsのコントローラは必ず
ApplicationController
を継承- Applicationコントローラで定義した内容は全てのアプリケーションに反映される
- サインイン・サインアウトのヘルパーメソッドを定義する、といった用途に使用できる
デモアプリケーションのデプロイ
- リポジトリをGitHubに登録
$ git add .
$ git commit -m "Finish demo app"
$ git push
- Herokuにデプロイ
$ heroku create
$ git push heroku master
- 本番DBのマイグレーション
$ heroku run rake db:migrate
まとめ
- この章でやれたこと
- Rails全体を高度なレベルで概観
- MVCモデルを確認
- RESTアーキテクチャに触れる
- データベースモデルを作成
- データベースを背後に持つWebアプリケーションを本番環境で動作させる