Download pdf - Ruby on Rails Tutorial

Transcript
Page 1: Ruby on Rails Tutorial

Ruby on RailsTutorial

1

Page 2: Ruby on Rails Tutorial

環境

Ruby 2.0.0

Rails 4.0.0

Bundler 1.3.5

SQLite 3.7.2

2

Page 3: Ruby on Rails Tutorial

Rails インストール

% mkdir -p tutorial% cd tutorial% bundle init% vi Gemfile% bundle install --path vendor/bundle

Gemfilesource "https://rubygems.org"

gem "rails"

3

Page 4: Ruby on Rails Tutorial

プロジェクト作成1

% bundle exec rails new . --skip-bundle

conflict GemfileOverwrite /path/to/tutorial/Gemfile? (enter "h" for help) [Ynaqdh] Enter(上書き)

よく使うオプション

オプション 値 説明-T test/unitを組み込まない

-d mysql/postgresql

利用するデータベースを指定。デフォルトはSQLite。

--skip-bundle bundle initを行わない

4

Page 5: Ruby on Rails Tutorial

プロジェクト作成2

% vi Gemfile% bundle

# See https://github.com/sstephenson/execjs#readme for more supported runtimes# 以下をアンコメントgem 'therubyracer', platforms: :ruby

Gemfile

% export PATH=`pwd`/bin:$PATH% rails -v

確認

5

Page 6: Ruby on Rails Tutorial

ディレクトリ構成ディレクトリ 説明説明

app

アプリケーションコードアプリケーションコード

app

assets image/stylesheet/javascript

appcontrollers コントローラ

app helpers ヘルパーappmailers メール

app

models モデル

app

views ビューbin bundle/rails/rake等のスクリプトbundle/rails/rake等のスクリプト

config 設定ファイル設定ファイルdb スキーマ/マイグレーションファイル及びSQLite DBスキーマ/マイグレーションファイル及びSQLite DBlib 独自ライブラリ/Rakeタスク独自ライブラリ/Rakeタスクlog ログファイルログファイル

public Webサーバに設定するDocumentRootWebサーバに設定するDocumentRoottest テストコード(RSpecを利用する場合はspec)テストコード(RSpecを利用する場合はspec)tmp TempファイルTempファイル

vendor 外部のライブラリ外部のライブラリ6

Page 7: Ruby on Rails Tutorial

rails/rakeコマンド

コマンド 説明rails server 開発用のWEBrickサーバを起動rails console Railsコンソールを起動rails dbconsole DBのクライアントを起動rails runner Rails環境でスクリプトを実行

コマンド 説明rake db:create 対象のデータベースを作成rake db:migrate マイグレーションファイルを実行rake db:rollback マイグレーションのロールバックを実行rake routes ルーティングの設定を確認rake assets:precompile アセットのコンパイル

7

Page 8: Ruby on Rails Tutorial

とりあえず起動してみる

% rails s

8

Page 9: Ruby on Rails Tutorial

Scaffold% rails generate scaffold blog title:string body:text% rake db:migrate

CRUDが簡単に作れるmodel/scaffoldを作成したら

`rake db:migrate`を実行してDBに反映させる

assets/controller/helper/model/view及びマイグレーションファイルをまとめて生成。

9

Page 10: Ruby on Rails Tutorial

個別で生成

% rails g model モデル名 カラム名:型 カラム名:型

% rails g controller コントローラ名 メソッド名

% rails g migration タスク名

db/migrate/YYYYmmddHHMMSS_task.rbが作成され、`rake db:migrate`でタスクを実行できる。主にテーブル作成/スキーマ変更に使う。

マイグレーション

コントローラ

assets/controller/helper/viewを作成する。メソッド名を指定しない場合は空のコントローラが作成される。

モデル

modelとマイグレーションファイルを作成する。カラムの型は主にstring/text/integer/float/boolean/date/time/timestampを使う。実際にDBに作成されるカラムの型はDBによって異なる。

10

Page 11: Ruby on Rails Tutorial

マイグレーションファイル

作成されたマイグレーションファイルはdb/migrate/に保存される

`rake db:migrate`でDBに反映する事ができる

反映後に戻したい時は`rake db:rollback`でロールバックできる

どこまで適用されているかはschema_migrationsテーブルで管理されている

class CreateBlogs < ActiveRecord::Migration def change create_table :blogs do |t| t.string :title t.text :body

t.timestamps end endend

マイグレーションファイルの中身

11

Page 12: Ruby on Rails Tutorial

リクエスト処理の流れ

router(routes.rb)

DBServer

controllers(controllers/*.rb)

models(models/*.rb)

views(views/*/

*.html.erb)

request routing

sql

response

12

Page 13: Ruby on Rails Tutorial

モデルapp/models/blog.rb

class Blog < ActiveRecord::Baseend

本来はバリデーション/アソシエーション/ビジネスロジック等を書くけど、これでもDB操作は可能

% rails c> blog = Blog.new> blog.title = "test title"> blog.body = "test body"> blog.save # blogsテーブルに新規レコードを作成> blogs = Blog.all # blogsテーブルの全てのレコードを取得> blogs.each {|b| puts b.title} # 取得したレコードのtitleカラムを出力> blog = Blog.find(1) # blogsテーブルからidが1のレコードを取得> puts blog.title # titleカラムを出力> blog.destroy # 取得したレコードをblogsテーブルから削除

モデルの操作例

13

Page 14: Ruby on Rails Tutorial

ルーティング1

Tutorial::Application.routes.draw do resources :blogsend

config/routes.rb

% rake routes Prefix Verb URI Pattern Controller#Action blogs GET /blogs(.:format) blogs#index POST /blogs(.:format) blogs#create new_blog GET /blogs/new(.:format) blogs#newedit_blog GET /blogs/:id/edit(.:format) blogs#edit blog GET /blogs/:id(.:format) blogs#show PATCH /blogs/:id(.:format) blogs#update PUT /blogs/:id(.:format) blogs#update DELETE /blogs/:id(.:format) blogs#destroy

上記のコードで設定されるルーティング

14

Page 15: Ruby on Rails Tutorial

ルーティング2

個別にルーティング設定をする場合

Tutorial::Application.routes.draw do controller :blogs do # HTTPMethod URI, to: ExecMethod, as: :Prefix # GET /index => BlogsController#index (index_path) get :index, to: :index, as: :index

# POST /create => BlogsController#create (create_path) post :create, to: :create, as: :create

# GET / => BlogsController#root (root_path) get :root, to: "blogs#root" endend

15

Page 16: Ruby on Rails Tutorial

コントローラ1

class BlogsController < ApplicationController before_action :set_blog, only: [:show, :edit, :update, :destroy]

def index @blogs = Blog.all end

def new @blog = Blog.new end

private def set_blog @blog = Blog.find(params[:id]) end

def blog_params params.require(:blog).permit(:title, :body) endend

app/controller/blogs_controller.rb

メソッドが無い又は空の場合はviewがレンダリングされる16

Page 17: Ruby on Rails Tutorial

コントローラ2

メソッド 説明

#index@blogsにblogsテーブルの全てのレコードを格納してviewをレンダリングする。

#new@blogにBlogモデルのオブジェクトを生成して格納し、viewをレンダリングする。

#show先のページではメソッドが無いが実際は空のメソッドが存在する。before_actionが設定されている為、set_blogメソッドを呼び出してviewをレンダリングする。

#editshowと同様にメソッドが無いが実際は空のメソッドが存在する。こちらもbefore_actionが設定されている為、set_blogメソッドを呼び出してviewをレンダリングする。

17

Page 18: Ruby on Rails Tutorial

コントローラ3class BlogsController < ApplicationController def create @blog = Blog.new(blog_params)

respond_to do |format| if @blog.save format.html { redirect_to @blog, notice: 'Blog was successfully created.' } format.json { render action: 'show', status: :created, location: @blog } else format.html { render action: 'new' } format.json { render json: @blog.errors, status: :unprocessable_entity } end end endend

Blogモデルのオブジェクトをstrong parameterを通したパラメータを引数に生成し、@blogに格納。@blog.save(DBに保存)して成功すればリダイレクト、失敗すればnewメソッドのviewをレンダリングする。

18

Page 19: Ruby on Rails Tutorial

コントローラ4

class BlogsController < ApplicationController def update respond_to do |format| if @blog.update(blog_params) format.html { redirect_to @blog, notice: 'Blog was successfully updated.' } format.json { head :no_content } else format.html { render action: 'edit' } format.json { render json: @blog.errors, status: :unprocessable_entity } end end endend

before_actionが設定されている為、set_blogメソッドを呼び出して@blog.updateでcreateと同様にstrong parameterを通したパラメータを引数にレコードをアップデートする。成功した場合はリダイレクトし失敗した場合はeditのviewをレンダリングする。

19

Page 20: Ruby on Rails Tutorial

コントローラ5class BlogsController < ApplicationController def destroy @blog.destroy respond_to do |format| format.html { redirect_to blogs_url } format.json { head :no_content } end endend

before_actionが設定されている為、set_blogメソッドを呼び出して@blog.destroyでレコードを削除。削除後にリダイレクトされる。

`respond_to {|format| ...}`はformatによってレンダリングする内容を指定している。

20

Page 21: Ruby on Rails Tutorial

ビュー1

<!DOCTYPE html><html><head> <title>Tutorial</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>

このファイルがHTMLをレンダリングする時にデフォルトで使用されるlayout。<%= yield %>の部分に対象のviewファイルで生成されたHTMLが入る。rubyのコードは<%= %>(出力あり)か<% %>(出力無し)の中に記述する。

app/views/layouts/application.html.erb

21

Page 22: Ruby on Rails Tutorial

ビュー2

<h1>Editing blog</h1>

<%= render 'form' %>

<%= link_to 'Show', @blog %> |<%= link_to 'Back', blogs_path %>

コントローラのメソッド内で`render`や`redirect_to`等が呼ばれない場合、app/views/コントローラ名/メソッド名.html.erb(formatがhtmlの場合)がレンダリングされる。また以下のedit.html.erbのように共通で利用する部分を`render`メソッドで読み込む事も可能。

app/views/blogs/edit.html.erb

22

Page 23: Ruby on Rails Tutorial

ログイン認証機能を付ける1

% vi Gemfile% bundle

ライブラリインストール

# 以下を追記gem "passwd"

Gemfile

Gemfileにてインストールしたライブラリを自動的に`require`される。(groupを指定したり、requireオプションをfalseにした場合以外)

2回目以降は.bundle/configにオプションが設定されているのでbundleのみで問題ない。

23

Page 24: Ruby on Rails Tutorial

ログイン認証機能を付ける2

% rails g controller sessions

ログイン/ログアウト用のSessionsコントローラを作成

Tutorial::Application.routes.draw do resources :blogs

# 以下を追加 controller :sessions do get :login, to: :new, as: :new_session post :login, to: :create, as: :create_session get :logout, to: :destroy, as: :delete_session endend

ルーティング設定config/routes.rb

% rake routes... new_session GET /login(.:format) sessions#newcreate_session POST /login(.:format) sessions#createdelete_session GET /logout(.:format) sessions#destroy

24

Page 25: Ruby on Rails Tutorial

ログイン認証機能を付ける3

<%= form_tag(create_session_path) do %>

<% if flash[:alert] %><%= flash[:alert] %><% end %>

<%= text_field_tag :email, nil, placeholder: "Email" %><%= password_field_tag :password, nil, placeholder: "Password" %><%= submit_tag "Send" %><% end %>

ログインページ作成(新規作成)app/views/sessions/new.html.erb

class SessionsController < ApplicationController def create render text: "login" end def destroy render text: "logout" endend

SessionsControllerにcreate/destroyメソッドを追加しておくapp/controllers/sessions_controller.rb

25

Page 26: Ruby on Rails Tutorial

ログイン認証機能を付ける4

% rails g model user email:string salt:string password:string% rake db:migrate

ユーザモデル作成

class User < ActiveRecord::Base include Passwd::ActiveRecord define_columnend

Userモデル編集app/models/user.rb

ユーザ作成

% rails c> user = User.new> user.email = "[email protected]"> user.set_password("secret")> user.save> puts password

26

Page 27: Ruby on Rails Tutorial

ログイン認証機能を付ける5

class SessionsController < ApplicationController def create @user = User.authenticate(params[:email], params[:password]) if @user session[:user] = @user.id redirect_to blogs_path else flash.now[:alert] = "Email or password is incorrect." render action: :new end end def destroy session[:user] = nil redirect_to blogs_path endend

ログイン/ログアウト処理app/controllers/session_controller.rb

27

Page 28: Ruby on Rails Tutorial

ブログの作成等を制限する1

class ApplicationController < ActionController::Base protect_from_forgery with: :exception

# 以下を追加 def require_logged_in if session[:user].present? begin @user = User.find(session[:user]) rescue ActiveRecord::RecordNotFound reset_session end end redirect_to create_session_path unless @user endend

ログインチェックのメソッドをApplicationControllerに定義app/controllers/application_controller.rb

application_controller.rbにメソッドを定義しておくと他のコントローラから利用可能になる。

28

Page 29: Ruby on Rails Tutorial

ブログの作成等を制限する2

class BlogsController < ApplicationController before_action :set_blog, only: [:show, :edit, :update, :destroy] # 以下を追加 before_action :require_logged_in, only: [:new, :edit, :create, :update, :destroy]

...end

new/edit/create/update/destroyにログイン制限をかける

before_actionで`require_logged_in`メソッドを呼び出し、ログインしていない場合はログインページにリダイレクトさせる

29