ruby on rails 基礎演習 - jenc.co.jp on rails 基礎演習 社会人技術者研修 2014年度...
TRANSCRIPT
!!
Ruby on Rails 基礎演習 社会人技術者研修 2014年度 テキスト
!!
2014.11
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 1
Ruby on RailsRuby on Railsテキスト
目的
近年盛んに利用されているRuby on Railsについて、基礎的なシステム要素、フレームワークの解説と、基本的な導入の流れまでを解説・実演・実習
達成目標
Ruby on Rails Ruby on Rails の導入基礎、システム全体像の基礎部分把握アジャイル開発の初歩を習得、既にあるコードを読んでいけるまでの理解その後各自がさらに習熟をすすめていけるところまでを目標
改訂・更新
2014.11 作成2015. 2 改訂
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 2
Ruby on RailsRuby on Railsテキスト 1章本テキストは、Ruby on Railsチュートリアル ( http://railstutorial.jp/) を主な参考情報として解説を進めます。
Ruby on RailsRuby on RailsとはRuby on Railsとは、Ruby言語をベースとする、Webアプリケーション用のフレームワークです。David Heinemeier Hansson氏によって開発され、オープンソース公開されています。
RailsRailsの普及と特徴
大人気のWebアプリケーションフレームワーク多くの組織や有名起業サービスがRailsを採用 ! Twitter,楽天,CookPad,GitHub,etc・・Webアプリケーションの生産性の高さ(特に動き出すまでの早さ)オープンソースとRuby言語の柔軟性プラグインツールの充実情報も開発コミュニティも豊富新しい技術のキャッチアップが速い、現在のRailsのバージョンは4.2が最新
WebWebアプリケーションフレームワーク
Webアプリケーションに限らずアプリケーション開発は、その分野にある一定の型/パターンになっていく傾向があります。毎回繰り返す基本設計や設計思想を定型化し再利用可能としてソフトウェア開発の生産性を向上しようとするものを「フレームワーク」と呼ぶ。Rubyはプログラミング言語であり、Ruby on Rails は Ruby言語を使用したフレームワークの一種という位置づけです。Ruby用のフレームワークは Rails の他にも sinatra、Padrino 等といったものが存在します。
開発環境の構築
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 3
http://railstutorial.jp/chapters/beginning?version=4.0#sec-up_and_runningを参考として環境構築
ターミナル
Railsの開発作業の多くはコマンドでの作業を伴います。Windowsであればコマンドプロンプト、MacやLinuxでは各種ターミナル
テキストエディタ
汎用のテキストエディタを用います(代表的なもの)
Sublime TextVim/ViTeraTermEmacsetc..
IDEIDEツール
RadRailsRubyMineetc..
WebWebブラウザ
各種(IE, FireFox, Crhome, Safari)
RailsRailsインストーラによる各種開発ツールのインストール
http://railsinstaller.org の提供されているサービスを利用して、何もないところからひと通りの必要なツール類をインストールすることができます。(Windows、OSXに対応しています)
インストールされるツール類
Ruby
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 4
BundlerRubyGemsDevKitRailsSqliteGit
動作環境
Ruby 2.0.0Rails 4.1
環境設定
インストールされているRubyRubyのバージョン確認
コマンドラインから確認
コマンド
ruby -v
開発プロジェクトごとに別々のRubyバージョンが必要となる場合は RVM または rbenvを利用(今回は割愛)
RubyGemsRubyGemsの確認
(Railsインストーラでは同時にまとめてインストールされている)
コマンド
$ gem
でgemコマンドがインストールされていなければ RubyGems のインストール
RailsRailsのインストール
(Railsインストーラでは同時にまとめてインストールされている)
コマンド
$ gem install rails --version 4.1.0
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 5
同様に
コマンド
$ rails -v
でバージョンの確認ができます。
GemfileGemfile
GemfileはRailsをインストールしたディレクトリ直下に格納されています。
変更点
Gemfile
ruby '2.0.0'
GitHubGitHub
GitHubのアカウントを登録し、自分のリポジトリを確保各種初期設定を済ましておきます。
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 6
Ruby on RailsRuby on Railsテキスト 2章Ruby on Railsチュートリアル ( http://railstutorial.jp/)第1章 最初のアプリケーションより
最初のアプリケーション
rails new rails new コマンドコマンド
$ rails -v4.0.0$ mkdir rails_projects$ cd rails_projects$ rails new first_app create create README.rdoc create Rakefile create config.ru create .gitignore create Gemfile create app create app/assets/javascripts/application.js create app/assets/stylesheets/application.css . . create vendor/assets/javascripts create vendor/assets/javascripts/.keep create vendor/assets/stylesheets create vendor/assets/stylesheets/.keep run bundle install..Your bundle is complete!Use `bundle show [gemname]` to see where a bundled gem is installed.
これだけで最小のRailsアプリケーションがインストールされた状態となります。
フォルダ構造
主要なフォルダについて
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 7
app/controllersapp/modelsapp/views モデル、ビュー、コントローラ、ヘルパーなどを含む主要なアプリケーションコード
app/assets アプリケーションで使用するCSS (Cascading Style Sheet)、JavaScriptファイル、画像などのアセット
config/ アプリケーションの設定
db/ データベース関連のファイル
log/ アプリケーションのログファイル
public/ エラーページなど、一般(Webブラウザなど)に直接公開するデータ
vendor/ サードパーティのプラグインやgemなど
Gemfile Gemfile.lock このアプリケーションに必要なGemの定義ファイル
.gitignore Gitに無視させたいファイルを指定するためのパターン
GemfileGemfileの変更
追加
Gemfile
ruby '2.0.0'
変更
Gemfile
group :development dodo gem 'sqlite3', '1.3.8' # heroku対応 endend
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 8
Gemfileを変更後、gemをインストール
コマンド
$ bundle update$ bundle install
Rails ServerRails Server
Railsはそれ自身で簡易のWebサーバー機能を内蔵しており、ローカルの環境でWebアプリケーションの起動が手軽のできます。
試しに手元のPCの中でサーバーを起動してみます。
コマンド
$ rails server(server は省略して s でも同じ動作です)=> Booting WEBrick=> Rails application starting on http://0.0.0.0:3000=> Call with -d to detach=> Ctrl-C to shutdown server
Webブラウザにて 127.0.0.1:3000(localhost:3000)を開くと、Railsマークの画面が開くのが確認できます。
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 9
※ Rails自身がローカルでWebサーバとなり、Railsアプリケーションがその上で動いている
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 10
Ruby on RailsRuby on Railsテキスト 3章Ruby on Railsチュートリアル ( http://railstutorial.jp/)第2章 デモアプリケーション より
UserUser画面の追加
generate scaffold generate scaffold コマンドコマンド
$ rails generate scaffold User name:string email:string invoke active_record create db/migrate/****_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 ・ ・ ・$$ rake db:migrate== CreateUsers: migrating =================================-- create_table(:users) -> 0.0017s== CreateUsers: migrated (0.0018s) ========================
scaffold コマンド1行で
一覧・表示・編集の表示テンプレートの登録(View)データベースとアクセスしモデルを定義する部分のコード定義(Model)リクエストを受付ける処理のひな形を定義(Controller)ユーザ名とメールアドレスのデータベース定義(migration)その他テスト用コード等
が一気に登録されます。(genarate は”ジェネレータ”で、コード等の自動生成追加などを行うコマンドです)
Rails serverを起動し、localhost:3000/users を表示させると
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 11
のようにユーザ一覧の原型のようなものが表示されます。この表示をカスタマイズしていくことでWeb画面を構築していきます。
scaffoldコマンドで自動定義されるアドレス(URL)は
URLURL アクション 用途
/users index すべてのユーザーを一覧表示するページ
/users/1 show id=1のユーザーを表示するページ
/users/new new 新規ユーザーを作成するページ
/users/1/edit edit id=1のユーザーを編集するページ
として構成されます。一覧からNew User をクリックすると
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 12
の新規入力画面になります。ユーザ名、メールアドレスを入力しCreate Userボタンを押すと
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 13
として、入力されたことが確認されます。一覧には
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 14
のように表示されます。このそれぞれの画面をデコレーションしていくこと、データの処理を追加していくことが、Railsアプリケーションでのプログラミング作業となっていきます。
どのファイルを編集いしていくか
scaffoldコマンドで追加されたファイルを見ていくと、app/views下には
コマンド
user$ ls app/views/layouts users
のように、usersフォルダが追加されているのがわかります。その下には
コマンド
user$ ls -1 app/views/users/_form.html.erbedit.html.erbindex.html.erbindex.json.jbuildernew.html.erbshow.html.erbshow.json.jbuilder
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 15
のように、***.html.erb のついたファイルがあります。各アクション名から察するにそれぞれのファイルが対応する表示になっていると予想できます。では一覧アクションに相当する index.html.erb を確認・変更してみます。
index.html.erb
1 <p id="notice"><%= notice %></p> 2 3 <h1>Listing Users</h1> 4 5 <table> 6 <thead> 7 <tr> 8 <th>Name</th> 9 <th>Email</th> 10 <th colspan="3"></th> 11 </tr> 12 </thead> 13 14 <tbody> 15 <% @users.eacheach dodo |user| %> 16 <tr> 17 <td><%= user.name %></td> 18 <td><%= user.email %></td> 19 <td><%= link_to 'Show', user %></td> 20 <td><%= link_to 'Edit', edit_user_path(user) %></td> 21 <td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td> 22 </tr> 23 <% endend %> 24 </tbody> 25 </table> 26 27 <br> 28 29 <%= link_to 'New User', new_user_path %>
HTMLのBODY要素内の部分だけのようなHTMLらしき内容が見られます。これをテンプレートと呼びます。その中で <% %> で囲まれた部分にRubyのコードがPHPのように埋め込まれているのがわかります。このhtml.erbファイルの中で、Ruby言語を用いてアクティブな動作をするスクリプトを記述していきます。 Railsはこのテンプレートファイルを解釈し、実際のHTMLデータに変換してブラウザに返す動作をしています。
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 16
試しに一行変更してみます。
index.html.erb
4 <p><%= Time.now %></p>
すると localhost:3000/users を開くと
のように時間表示が追加されました。画面を作っていくのはViewにあるテンプレートを主に編集していく作業となります。
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 17
Ruby on RailsRuby on Railsテキスト 4章Ruby on Railsチュートリアル ( http://railstutorial.jp/)第2章 デモアプリケーション より
MVCMVCについて
MVCとは「Model」「View」「Controller」の頭文字をとって呼ばれています。
1. ブラウザは/usersというURLへのリクエストを発行する。 2. Railsは/usersをUsersコントローラ内のindexindexアクションに割り当てる (ルーティング)。
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 18
3. indexindexアクションはUserモデルに「すべてのユーザーを取り出せ」と指示する (User.all)。 4. Userモデルはすべてのユーザーをデータベースから取り出す。 5. Userモデルはユーザーの一覧をコントローラに返す。 6. コントローラはユーザーの一覧を@users変数に保存し、indexindexビューに渡す。 7. ビューは、その中に埋め込まれているRubyを使用してHTMLを生成する。 8. コントローラは、生成されたHTMLをブラウザに返す3。
MVCモデルとは、ユーザーインタフェイス部分(View)とデータ構造(Model)を切り離し、Controllerで結合する構成にすることでシステム設計をより容易にしていこうとするプログラミングモデルです。MVCモデルはWebアプリケーションプログラミングとも親和性が高く、各種のWebアプリケーションフレームワークで採用されています。
Railsのアプリケーションの基本構造はこのMVCに沿って構成されていくものとなります。
ControllerControllerについて
Railsプロジェクトにおけるコントローラ(Controller)に相当する部分はapp/controlers 以下にあります。Usersでscaffold生成した場合は app/controlers/users_controller.rb がusers のコントローラとなります。
users_controller.rb を見てみると、
class UsersController < ApplicationController def index ...... end
def show ...... end
def new ...... end
def create ...... end
def edit ...... end
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 19
def update ...... end
def destroy ...... endend
先ほどの一覧や新規作成ページURLと対応した名前のRubyクラスのメソッドがあることがわかります。
RailsはHTTPリクエストで与えられたURLを解析し、それに対応するモデルのコントローラのメソッド(アクション)を呼び出しているのだとわかります。
HTTPHTTPリクエスト URLURL アクショ
ン 用途
GET /users index すべてのユーザーを表示するページ
GET /users/1 show id=1のユーザーを表示するページ
GET /users/new new ユーザーを新規作成するページ
POST /users create ユーザーを作成するアクション
GET /users/1/edit edit id=1のユーザーを編集するページ
PATCH /users/1 update id=1のユーザーを更新するアクション
DELETE /users/1 destroy id=1のユーザーを削除するアクション
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 20
※ 上図のようなURLでのスタイルを「RESTスタイル」と呼ばれます 参考ja.wikipedia.org/wiki/REST※ リクエストURLをどのアクションに対応していくかは ルーティング設定情報(config/route.rb)をもとに割り振られます
コントローラはApplicationControllerクラスからの継承となっている。基本クラスの中にコントローラとしての機能が集約されており、アプリケーションプログラマはそのアーキテクチャに沿ってアプリケーション独自の追加機能を搭載していくこととなります。
RESTスタイルに沿って、コントローラの中に対応するメソッドが呼ばれることを念頭においてコントローラをの各アクションメソッドを設計・構築していきます。
ModelModelについて
RailsにおけるModelは、モデル/データ構造/データベースを司る要素として機能します。
Railsプロジェクトにおけるモデル(Model)に相当する部分は app/models 以下にあります。
Usersでscaffold生成した場合は app/models/user.rb が user のモデルとなります。user.rb を見てみると、
classclass UserUser < < ActiveRecordActiveRecord:::Baseend
とだけあります。モデルの基本クラスは ActiveRecord::Base クラスであり、データの入出力・データベース接続はこのクラスが一手に引き受けて動作しています。
※ データベースとの接続情報は db/ および config/ 以下にある情報を参照しています。
各モデルとView、Controllerが直接データベースを操作することをせず、modelの中にまとめていく設計・構築していくことで保守性の高いシステムとなります。
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 21
Ruby on RailsRuby on Railsテキスト 5章Ruby on Railsチュートリアル ( http://railstutorial.jp/)第2章 デモアプリケーション より
データの検証・連携
次にUserからの投稿機能を追加していきます
ユーザ投稿機能を追加
Micropostというモデルでscaffold追加してみます。
コマンド
$ rails generate scaffold Micropost content:string user_id:integer invoke active_record create db/migrate/*****_create_microposts.rb create app/models/micropost.rb invoke test_unit create test/models/micropost_test.rb create test/fixtures/microposts.yml invoke resource_route route resources :microposts invoke jbuilder_scaffold_controller create app/controllers/microposts_controller.rb invoke erb create app/views/microposts create app/views/microposts/index.html.erb create app/views/microposts/edit.html.erb create app/views/microposts/show.html.erb create app/views/microposts/new.html.erb create app/views/microposts/_form.html.erb ・ ・$ rake db:migrate== CreateMicroposts: migrating =============================-- create_table(:microposts) -> 0.0023s== CreateMicroposts: migrated (0.0026s) ======================$
rake db:migrate は、データベースのテーブルやカラムなどの追加・変更・削除等を記述されたスクリプトを実行するコマンドです。scaffoldコマンドではデータベーステーブルの追加・変化があるため、その直後に
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 22
migrationしてデータベースに反映します。
scaffoldでmicropostモデルのMVCが自動生成され、config/routes.rbにはそれに対応したRESTのルーティング設定が追加されます。
1 Rails.application.routes.draw dodo 2 resources :microposts #←追加されている 3
Micropostモデルの RESTインタフェイスが出来たのをひと通り確認し適当な入力を行います。
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 23
データの検証機能の追加(ValidationValidation)
Railsのモデルクラス(すなわちActiveRecordクラス)には、データの入力に際してチェックを施す機能が組み込まれており、簡単にその機能を派生クラス側で利用することができます。
(例)入力文字数を140字に制限
app/models/micropost.rb
classclass MicropostMicropost < < ActiveRecordActiveRecord:::Base validates :content, length: { maximum: 140 }end
たったこれだけで、Micropostのcontentの入力に140字までの制限が加わりました。試しに141文字の入力をしようとしてみると、以下のようなエラー表示が出てきます。
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 24
検証機能についてはその他にも豊富な記述があります。http://railsdoc.com/validation 等を参照
データの連携
UserとMicropostをユーザIDで関連付け、リレーションを行うものとします。その指定もきわめてシンプルに記述できるのがRailsの強力な機能のひとつです。
1対多関連(has_manyhas_many)
ひとりのユーザには多数の投稿があるとする。 Userモデルに以下の記述を追加
app/models/user.rb
classclass UserUser < < ActiveRecordActiveRecord:::Base has_many :micropostsend
ひとつの投稿には1人の投稿者によるものとする。Micropostモデルに以下の記述を追加
app/models/micropost.rb
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 25
classclass MicropostMicropost < < ActiveRecordActiveRecord:::Base belongs_to :user validates :content, length: { maximum: 140 }end
以上の記述だけで、user_idをもとにしてユーザ情報と投稿情報を関連づけができるようになります。
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 26
Ruby on RailsRuby on Railsテキスト 6章Ruby on Railsチュートリアル ( http://railstutorial.jp/)第1章 Gitによるバージョン管理より
HerokuHerokuサービスを利用したWebWeb公開
GitGitによるバージョン管理
最初のセットアップ
コマンド
$ git config --global user.name "あなたの名前"$ git config --global user.email [email protected]
Railsアプリケーションのルートディレクトリから最初のリポジトリのセットアップ
初期化
コマンド
$ git init
まずプロジェクトで履歴管理の不要なファイル種類の指定(.gitignoreファイルをプロジェクトのルートに置く)
.gitignore
# 一般的な.gitignoreの例# Ignore bundler config./.bundle
# Ignore the default SQLite database./db/*.sqlite3/db/*.sqlite3-journal
# Ignore all logfiles and tempfiles./log/*.log/tmp
# Ignore other unneeded files.doc/*.swp*~.project
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 27
.DS_Store
.idea
.secret
続いてプロジェクトのファイルをリポジトリ追加
コマンド
$ git add .
ステージングされたファイルの確認
コマンド
$ git status
ステージングしたファイルの保存
コマンド
$ git commit -m "Initialize repository" (-mオプションはコメント入力)
GitHubGitHubの利用
RailsインストーラでGitHubアカウントを登録していない場合は GitHub.com にてユーザ登録、初期設定。GitHubでリポジトリ(今回はfirst_app)を作成し、以下を実行してアプリケーションをプッシュ。
コマンド
$ git remote add origin https://github.com/<username>/first_app.git (<username>は各ユーザのアカウント名)$ git push -u origin master
(例)プッシュ直後のGitHubリポジトリページ
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 28
HerokuHerokuの利用
HerokuというPaaSサービスを利用ユーザ登録しHeroku Toolbeltのインストール本番 (production) 環境にpg gemをインストールしてRailsがPostgreSQLと通信できるようにします。
Gemfileの編集
Gemfile
group :production dodo gem 'pg', '0.15.1' # PostgreSQLを使用 gem 'rails_12factor', '0.0.2' # Heroku用の設定endend
その他変更(各環境により異なる)
Gemfile
source 'https://rubygems.org'ruby '2.0.0'#ruby-gemset=railstutorial_rails_4_0
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 29
gem 'rails', '4.0.5'
group :development dodo gem 'sqlite3', '1.3.8'endend
gem 'sass-rails', '4.0.5'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 dodo gem 'sdoc', '0.3.20', require: falsefalseendend
group :production dodo gem 'pg', '0.15.1' gem 'rails_12factor', '0.0.2'endend
再度bundle installします。
コマンド
$ bundle install --without production
リポジトリに格納
コマンド
git commit -a -m "Update Gemfile.lock for Heroku"
heroku create コマンドで新しいアプリケーションの作成
コマンド
$ heroku createupdate_your_git_clients_on_windows_and_os_xCreating stark-woodland-1937... donedone, stack is cedar-14https://stark-woodland-1937.herokuapp.com/ | https://git.heroku.com/stark-woodland-1937.gitGit remote heroku added
$ git remote -vheroku https://git.heroku.com/stark-woodland-1937.git (fetch)heroku https://git.heroku.com/stark-woodland-1937.git (push)
Herokuのpostgresqlアドオンを追加
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 30
コマンド
$ heroku addons:add heroku-postgresqlYour version of git is 1.9.3. Which has serious security vulnerabilities.More information here: https://blog.heroku.com/archives/2014/12/23/update_your_git_clients_on_windows_and_os_x
Adding heroku-postgresql on stark-woodland-1937... donedone, v4 (free)Attached as HEROKU_POSTGRESQL_PINK_URLDatabase has been created and is available ! This database is empty. If upgrading, you can transfer ! data from another database with pgbackups:restore.Use `heroku addons:docs heroku-postgresql` to view documentation.
Herokuに登録されたpostgresqlの設定情報を調べる
postgres.heroku.com/databases/***
Host ec2-107-21-104-188.compute-1.amazonaws.comDatabase d2cgntj5fk4q9sUser fluagxzuqhclkoPort 5432Password ShowPsql heroku pg:psql --app stark-woodland-1937 HEROKU_POSTGRESQL_PINKURL Show
config/database.ymlに設定情報を格納
database.yml
development: adapter: postgresql encoding: utf8 database: your_database port: 5432 username: your_username password: your_password
Herokuにデプロイ
コマンド
git push heroku masterCounting objects: 3068, donedone.Delta compression using up to 4 threads.Compressing objects: 100% (2914/2914), donedone.Writing objects: 100% (3062/3062), 8.85 MiB | 597.00 KiB/s, donedone.Total 3062 (delta 497), reused 0 (delta 0)remote: Compressing source files... donedone.remote: Building source:
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 31
remote: remote: -----> Ruby app detectedremote: -----> Compiling Ruby/Rails・・remote: -----> Compressing... donedone, 26.9MBremote: -----> Launching... donedone, v7remote: https://stark-woodland-1937.herokuapp.com/ deployed to Herokuremote: remote: Verifying deploy... donedone.To https://git.heroku.com/stark-woodland-1937.git b0988ab..fd07c5d master -> master
heroku run rake db:migrateupdate_your_git_clients_on_windows_and_os_xRunning `rake db:migrate` attached to terminal... up, run.5763・・== 20150224195623 CreateUsers: migrating ======================================・・== 20150224212423 CreateMicroposts: migrating =================================
※ HerokuもRailsも頻繁にバージョンアップされているので各種情報を確認して対応が必要
無事デプロイおよDBのマイグレーションが住んだならインターネット上に自分のアプリケーションが公開されている。
database.yml
$ heroku open
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 32
※ Rails4.x の最初はエラー表示から(この状態でHeroku上でRailsは既に動いている)/users および /microposts で一覧が確認できます。
これで手元で開発したアプリケーションをインターネット上のWebアプリケーションとして動作させることができました。ローカルで開発・テストを進め、Herokuへ本番公開という作業の流れとなります。なおサブドメイン名はherokuのコントロールパネルで、任意の名に変更可能です。
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 33
Ruby on RailsRuby on Railsテキスト 7章Ruby on Railsチュートリアル ( http://railstutorial.jp/)第6章 Userモデル より
マイグレーションファイル
generate scaffhold で Userモデル を作成した場合、以下のマイグレーションファイルが生成されています。以下の例では usersテーブルの作成、name,email,タイムスタンプのカラムを生成しています。
db/migrate/[timestamp]_create_users.rb
classclass CreateUsersCreateUsers < < ActiveRecord::MigrationActiveRecord::Migration defdef changechange create_table :users dodo |t| t.string :name t.string :email
t.timestamps endend endendendend
マイグレーションの適用(データベースの操作)は以下のコマンドで行います。
コマンド
$ bundle exec rake db:migrate
マイグレーションのロールバック(元に戻す)操作もあり、以下の例では1つマイグレーションを戻す指示を行います。
コマンド
$ bundle exec rake db:rollback
基本的なRailsアプリケーションでのデータベース操作は、各種のデータベースシステム専用のコマンドやツールを使わず、マイグレーションファイルの操作だけで管理ができるようになります。 これによりMySQL、PostgreSQL、Oracleなど異なったデータベースと接続したシステムを構築する場合でもまったく同じ手順でテーブル管理ができるようになります。
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 34
RailsRailsコンソール
Webサーバーとして動作させる時に rails server コマンドを使用しましたが、RubyのIRBコンソールと同様に対話形式でRailsアプリケーションを操作することができます。
コマンド
$ rails console >> 1=> 1>> exitexit$
終了はIRBと同様にexitです。この状態でIRBと同様の対話コマンドが入力可能です。--sandboxパラメータを指定して起動すると、アプリケーションに接続されているデータベースの内容を保護した状態で起動します。
コマンド
$ rails console --sanbbox
userを追加してみます。
コマンド
>> User.new=> #<User id: nil, name: nil, email: nil, created_at: nil, updated_at: nil>>>>> user = User.new(name: "example", email: "[email protected]")=> #<User id: nil, name: "example", email: "[email protected]",created_at: nilnil, updated_at: nilnil>>>>> user.save=> truetrue>>>> user=> #<User id: 1, name: "example", email: "[email protected]",created_at: "2014-09-26 00:57:46", updated_at: "2014-09-26 00:57:46">>>>> user.name=> "[email protected]">>
このように対話的にモデル(とそれを格納しているデータベース内容)を簡単に操作できます。Varidationの検証などわざわざWebサーバーを起動せずとも確認できます。railstutorialの6章後半にそのことが詳しく解説されています。
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 35
Ruby on RailsRuby on Railsテキスト 8章Ruby on Railsチュートリアル ( http://railstutorial.jp/)第8章 サインイン、サインアウト~第10章ユーザーのマイクロポスト等を参照して各種コードの追加例を解説
ユーザ一覧・追加・編集画面の編集
電話番号、コメント情報を追加
コマンド
$ bundle exec rails g migration add_tel_number_to_users$ bundle exec rails g migration add_comment_to_users
マイグレーションファイルの編集
****_add_tel_number_to_users
classclass AddTelNumberToUsersAddTelNumberToUsers < < ActiveRecord::MigrationActiveRecord::Migration defdef changechange add_column :users, :tel, :string endendendend
****_add_comment_to_users
classclass AddCommentToUsersAddCommentToUsers < < ActiveRecord::MigrationActiveRecord::Migration defdef changechange add_column :users, :comment, :string endendendend
マイグレーション
コマンド
$ bundle exec rake db:migrate
userモデル(ユーザ情報)
app/models/user.rb
classclass UserUser < < ActiveRecord::BaseActiveRecord::Base validates :name, :length => { :minimum => 8, :maximum => 12} ## 名前の長さ制限 has_many :micropostsendend
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 36
usersコントローラ ※特に変更なし
app/controllers/users_controller.rb
classclass UsersControllerUsersController < < ApplicationControllerApplicationController before_action :set_user, only: [:show, :edit, :update, :destroy]
defdef welcomewelcome endend
# GET /users # GET /users.json defdef indexindex @users = User.all endend
# GET /addr defdef addraddr @users = User.all endend
defdef addr_showaddr_show @user = User.find(params[:id]) endend
defdef contents_showcontents_show ## 追加(投稿内容の表示一覧) @user = User.find(params[:id]) endend
# GET /users/1 # GET /users/1.json defdef showshow endend
# GET /users/new defdef newnew @user = User.new endend
# GET /users/1/edit defdef editedit endend
# POST /users # POST /users.json defdef createcreate @user = User.new(user_params)
respond_to dodo |format| ifif @user.save format.html { redirect_to @user, notice: 'User was
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 37
successfully created.' } format.json { render action: 'show', status: :created, location: @user } elseelse format.html { render action: 'new' } format.json { render json: @user.errors, status: :unprocessable_entity } endend endend endend
# PATCH/PUT /users/1 # PATCH/PUT /users/1.json defdef updateupdate respond_to dodo |format| ifif @user.update(user_params) format.html { redirect_to @user, notice: 'User was successfully updated.' } format.json { head :no_content } elseelse format.html { render action: 'edit' } format.json { render json: @user.errors, status: :unprocessable_entity } endend endend endend
# DELETE /users/1 # DELETE /users/1.json defdef destroydestroy @user.destroy respond_to dodo |format| format.html { redirect_to users_url } format.json { head :no_content } endend endend
private # Use callbacks to share common setup or constraints between actions. defdef set_userset_user @user = User.find(params[:id]) endend
# Never trust parameters from the scary internet, only allow the white list through. defdef user_paramsuser_params params.requirerequire(:user).permit(:name, :email, :tel, :comment) endendendend
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 38
contents_showアクションを追加したのでルーティング情報を追加
config/routes.rb
get "users/:id/contents", :controller => 'users', :action => 'contents_show'
ユーザー一覧表示を編集、テーブル形式に
app/views/users/index.html.erb
<h1>ユーザ一覧</h1><hr><table border="1"> <thead> <tr> <th>名前</th> <th>メールアドレス</th> <th>電話番号</th> <th>コメント</th> <th></th> <th></th> <th></th> <th></th> </tr> </thead> <tbody> <% @users.each do |user| %> <tr> <td><%= user.name %></td> <td><%= user.email %></td> <td><%= user.tel %></td> <td> <%= simple_format(user.comment) %> </td> <td><%= link_to '表示', user %></td> <td><%= link_to '編集', edit_user_path(user) %></td> <td><%= link_to '削除', user, method: :delete, :data => { :confirm => 'よろしいですか?' } %></td> <td><%= link_to 'コンテンツ', "/users/#{user.id}/contents" %></td> </tr> <% end %> </tbody></table><%= link_to '新規ユーザ登録', 'users/new' %>
ユーザー登録・編集画面
app/views/users/new.html.erb
<h1>新規ユーザ登録</h1>
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 39
<%= render 'form' %><%= link_to '戻る', users_path %>
app/views/users/edit.html.erb
<h1>ユーザ編集</h1><%= render 'form' %><%= link_to '表示', @user %> |<%= link_to '戻る', users_path %>
ユーザー編集フォーム
app/views/users/_from.html.erb
<%= form_for(@user) dodo |f| %> <% ifif @user.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(@user.errors.count, "error") %> prohibited this user from being saved:</h2> <ul> <% @user.errors.full_messages.eacheach dodo |msg| %> <li><%= msg %></li> <% endend %> </ul> </div> <% endend %> <div class="field"> <%= f.label '名前' %> <br> <%= f.text_field :name %> </div> <div class="field"> <%= f.label "メールアドレス" %> <br> <%= f.text_field :email %> </div> <div class="field"> <%= f.label "電話番号" %> <br> <%= f.text_field :tel %> </div> <div class="field"> <%= f.label "コメント" %> <br> <%= f.text_area :comment, :rows => "5" %> </div> <div class="actions"> <%= f.submit "登録", :style => "width:100px", :confirm => "よろしいですか?" %> </div><% endend %>
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 40
ユーザー表示画面
app/views/users/show.html.erb
<p id="notice"><%= notice %></p><p> <strong>名前:</strong> <%= @user.name %></p><p> <strong>メールアドレス:</strong> <%= @user.email %></p><p> <strong>電話番号:</strong> <%= @user.tel %></p><p> <strong>コメント:</strong> <%= simple_format(@user.comment) %></p><%= link_to '編集', edit_user_path(@user) %> |<%= link_to '一覧に戻る', users_path %>
moicropostモデル(投稿情報)
app/models/user.rb
classclass MicropostMicropost < < ActiveRecord::BaseActiveRecord::Base belongs_to :user validates :content, length: { maximum: 140 } ## 投稿を140文字以内に制限endend
micropostsコントローラ
classclass MicropostsControllerMicropostsController < < ApplicationControllerApplicationController before_action :set_micropost, only: [:show, :edit, :update, :destroy]
# GET /microposts # GET /microposts.json defdef indexindex @microposts = Micropost.all endend
# GET /microposts/1 # GET /microposts/1.json defdef showshow endend
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 41
# GET /microposts/new defdef newnew @micropost = Micropost.new @user_list = User.all.map{|user| [user.name, user.id] } endend
# GET /microposts/1/edit defdef editedit @user_list = User.all.map{|user|{user.id => user.name}} endend
# POST /microposts # POST /microposts.json defdef createcreate @micropost = Micropost.new(micropost_params)
respond_to dodo |format| ifif @micropost.save format.html { redirect_to @micropost, notice: 'Micropost was successfully created.' } format.json { render action: 'show', status: :created, location: @micropost } elseelse format.html { render action: 'new' } format.json { render json: @micropost.errors, status: :unprocessable_entity } endend endend endend
# PATCH/PUT /microposts/1 # PATCH/PUT /microposts/1.json defdef updateupdate respond_to dodo |format| ifif @micropost.update(micropost_params) format.html { redirect_to @micropost, notice: 'Micropost was successfully updated.' } format.json { head :no_content } elseelse format.html { render action: 'edit' } format.json { render json: @micropost.errors, status: :unprocessable_entity } endend endend endend
# DELETE /microposts/1 # DELETE /microposts/1.json defdef destroydestroy @micropost.destroy respond_to dodo |format|
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 42
format.html { redirect_to microposts_url } format.json { head :no_content } endend endend
private # Use callbacks to share common setup or constraints between actions. defdef set_micropostset_micropost @micropost = Micropost.find(params[:id]) endend
# Never trust parameters from the scary internet, only allow the white list through. defdef micropost_paramsmicropost_params params.requirerequire(:micropost).permit(:content, :user_id) endendendend
投稿登録・編集画面
app/views/microposts/new.html.erb
<h1>投稿編集</h1><%= render 'form' %><%= link_to 'Show', @micropost %>
投稿編集フォーム
app/views/microposts/_from.html.erb
<%= form_for(@micropost) dodo |f| %> <% ifif @micropost.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(@micropost.errors.count, "error") %> prohibited this micropost from being saved:</h2> <ul> <% @micropost.errors.full_messages.eacheach dodo |msg| %> <li><%= msg %></li> <% endend %> </ul> </div> <% endend %> <div class="field"> <%= f.label :content %><br> <%= f.text_area :content, :rows => "5"%> </div> <div class="field"> <%= f.label :user_id %><br> <%= f.selectselect :user_id, User.all.map{|user| [user.name, user.id] } %> </div>
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 43
<div class="actions"> <%= f.submit %> </div><% endend %>
投稿表示画面
app/views/microposts/show.html.erb
<p id="notice"><%= notice %></p><p> <strong>名前:</strong> <%= @user.name %></p><p> <strong>メールアドレス:</strong> <%= @user.email %></p><p> <strong>電話番号:</strong> <%= @user.tel %></p><p> <strong>コメント:</strong> <%= simple_format(@user.comment) %></p><%= link_to '編集', edit_user_path(@user) %>
一覧画面と投稿内容表示
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 44
投稿でTwitterTwitterに投稿するテスト
Railsには強力で大量の拡張のライブラリ(Gem)があり、さまざまな機能をアドインしていくことができます。今回はごく簡単にTwitterのタイムラインへの投稿を行ってみます。
Gemfileに twitter Gemを追加し bundle install
Gemfile
gemgem "twitter"
Twitter developpers サイトから各自のアカウントの認証キーを取得し、今回はコントローラに直接記述
以下は参考例
app/controllers/microposts_controller.rb
classclass MicropostsControllerMicropostsController < < ApplicationControllerApplicationController before_action :set_micropost, only: [:show, :edit, :update, :destroy] ## 指定メソッドの後処理の指定
# GET /microposts # GET /microposts.json
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 45
defdef indexindex @microposts = Micropost.all endend
# GET /microposts/1 # GET /microposts/1.json defdef showshow endend
# GET /microposts/new defdef newnew @micropost = Micropost.new @user_list = User.all.map{|user| [user.name, user.id] } endend
# GET /microposts/1/edit defdef editedit @user_list = User.all.map{|user|{user.id => user.name}} endend
# POST /microposts # POST /microposts.json defdef createcreate @micropost = Micropost.new(micropost_params)
respond_to dodo |format| ifif @micropost.save twit("新規:"[email protected]) ## 新規投稿のツイート format.html { redirect_to @micropost, notice: 'Micropost was successfully created.' } format.json { render action: 'show', status: :created, location: @micropost } elseelse format.html { render action: 'new' } format.json { render json: @micropost.errors, status: :unprocessable_entity } endend endend endend
# PATCH/PUT /microposts/1 # PATCH/PUT /microposts/1.json defdef updateupdate respond_to dodo |format| ifif @micropost.update(micropost_params) twit("編集:"[email protected]) ## 編集投稿のツイート format.html { redirect_to @micropost, notice: 'Micropost was successfully updated.' } format.json { head :no_content } elseelse format.html { render action: 'edit' }
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 46
format.json { render json: @micropost.errors, status: :unprocessable_entity } endend endend endend
# DELETE /microposts/1 # DELETE /microposts/1.json defdef destroydestroy @micropost.destroy respond_to dodo |format| format.html { redirect_to microposts_url } format.json { head :no_content } endend endend
private # Use callbacks to share common setup or constraints between actions. defdef set_micropostset_micropost ## 後処理で呼び出されるメソッド @micropost = Micropost.find(params[:id]) endend
# Never trust parameters from the scary internet, only allow the white list through. defdef micropost_paramsmicropost_params params.requirerequire(:micropost).permit(:content, :user_id) endend
defdef twittwit(tweet) ## Twitterへのツイート client = Twitter::REST::Client.new dodo |config| config.consumer_key = "****qKgOnL4kdiYIloAh0RDtO" config.consumer_secret = "****Mpj2kbDsecxrMtFUqwRmhbKy85zE3BRgCbv05IXxQuuZmk" config.access_token = "****178915-IiA5dVWDSOCIdPQEWZo81r1c9p1NBEcgwyXem1k" config.access_token_secret = "****HjAcq5pCQz9x49cV2oi7YQovPTBvCAujytlr684pq" endend beginbegin tweet = (tweet.length > 140) ? tweet[0..139].to_s : tweet client.update(tweet.chomp) rescuerescue => e ## ツイートエラー処理 Rails.logger.error "<<twitter.rake::tweet.update ERROR : #{e.message}>>" endend endendendend
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 47
以上のコードでmicropostの投稿・更新があるたびにツイート発信されるようになります。強力なGemのおかげで僅かなコード追加だけでtwitterへの投稿機能が追加できます。
簡易のユーザ認証動作
全てのリクエストを実行する前に、認証チェックを行う動作を追加します。ApplicationController は他のControllerの基本クラスとなっているため、そこに before_filter を追加しユーザ認証動作を行わせます。
app/controllers/application_controller.rb
classclass ApplicationControllerApplicationController < < ActionController::BaseActionController::Base
protect_from_forgery with: :exception before_filter :authorize ## 全てのリクエストのアクションを呼び出す前にauthorizeメソッドを実行
defdef authorizeauthorize ## ユーザ認証コード(簡易) ifif session[:login] != truetrue redirect_to signin_path ## ログイン状態でないならばログイン画面へリダイレクト endend endendendend
ログイン操作を受け付けるコントローラを追加以下はセッション情報にログイン状態を格納する例
app/controllers/sessions_controller.rb
classclass SessionsControllerSessionsController < < ApplicationControllerApplicationController skip_before_filter :authorize
defdef createcreate ifif params[:session][:password] == "secret" ## テスト用 session[:login] = truetrue redirect_to users_path elseelse session[:login] = falsefalse redirect_to signin_path, alert: "パスワードが間違っています。" ## パスワードエラーの場合のメッセージ表示 endend endend
defdef newnew endend
defdef destroydestroy
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 48
session[:login] = falsefalse redirect_to signin_path, alert: "ログアウトしました。" ## ログアウト時のメッセージ表示 endendendend
ログイン画面のビュー
app/views/sessions/new.html.erb
<h1>サインイン</h1>
<div> <% ifif flash[:alert] %> <p><%= flash[:alert] %></p> <% endend %></div>
<%= form_for(:session, url: sessions_path) dodo |f| %>
<%#= f.label :email %> <%#= f.text_field :email %>
<%= f.label :password %> <%= f.password_field :password %>
<%= f.submit "Sign in" %><% endend %>
ルーティング情報にログイン操作のルートを追加
config/routes.rb
Rails.application.routes.draw dodo
## セッション resources :sessions, only: [:new, :create, :destroy] match '/signup', to: 'users#new', via: 'get' match '/signin', to: 'sessions#new', via: 'get' match '/signout', to: 'sessions#destroy', via: 'delete'
resources :microposts resources :users
get "addr", :controller => 'users', :action => 'addr' get "addr/:id", :controller => 'users', :action => 'addr_show'
get "users/:id/contents", :controller => 'users', :action => 'contents_show'
#root 'users#welcome' root 'sessions#new' ## ルートURLはログイン画面に
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 49
endend
これで簡易なユーザー認証動作が追加されました。サーバー起動してroot表示してみるとこのような画面となります。
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 50
Ruby on RailsRuby on Railsテキスト 9章Ruby on Railsチュートリアル ( http://railstutorial.jp/)その他の情報
その他主要要素
CSS, JavascriptCSS, Javascriptの記述
スタイルシートやJavascript、画像などは一般的に app/assets以下に格納
最近のRailsにはcssやjs類をひとまとめに圧縮し動作高速化するための機構(AssetPipeline)があり、その機能を活用するために assets 以下に各情報をまとめて格納します。Railsにおけるスタイルシート、Javascriptの記述指定には一定のルールがあり、詳しくは各情報を参照。
ビューのレイアウトファイル
HTML文書を構成する他の要素(ヘッダやフッタ)は、views/layoutes/application.html.erb に記述されています。
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 51
app/views/application.html.erb
<!DOCTYPE html><!DOCTYPE html><html><head> <title>Railstext</title> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> <%= csrf_meta_tags %></head><body>
<%= yield %> ## ←この中に各画面のテンプレートが挿入される
</body></html>
application.html.erb とは別に users.html.erb ファイルを格納した場合は、usersコントローラのレイアウトファイルとして動作する。(他にもレイアウトを任意指定する記述方法もあります)
静的ページ
Railsに依存しない静的なページを置く場合は ルート直下の publicフォルダにHTMLファイル等を格納します。
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 52
Ruby on RailsRuby on Railsテキスト 参考情報
参考情報
チュートリアルテキスト
長期間をかけて習得していく場合はこちらのテキストを !http://railstutorial.jp/特にテスト技法を本テキストでは省略しているため、きちんと学ぶ場合はしっかりとチュートリアルに習うとよい
文献
以下のRails本などをおすすめ(基本的にオープンソースなのでたいがいの情報はオンラインで手に入るが、学習方法について学べます)
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 53
オンラインドキュメント
http://rubyonrails.org/Railsの本家サイト。最新の情報はまずここから
http://railsdoc.com/rails_base 多くの一般的なRailsの情報がよくまとめられています。
社会人技術者研修2014年度 Ruby on Rails 基礎演習テキスト 54