61
浜松Rails3道場 其の参 ControllerHamamatsurb#5 2011.08.10 @mackato 11816日火曜日

浜松Rails3道場 其の参 Controller編

Embed Size (px)

DESCRIPTION

2011/08/10のHamamatsu.rb#6で使った資料です。

Citation preview

Page 1: 浜松Rails3道場 其の参 Controller編

浜松Rails3道場其の参 Controller編

Hamamatsurb#5 2011.08.10 @mackato

11年8月16日火曜日

Page 2: 浜松Rails3道場 其の参 Controller編

浜松Rails3道場の心得

習うより慣れろ

理論より実用

未知を恐れない

11年8月16日火曜日

Page 3: 浜松Rails3道場 其の参 Controller編

実際にRailsアプリを作ってみる

Wiki

全5回位で

11年8月16日火曜日

Page 4: 浜松Rails3道場 其の参 Controller編

Wikiの仕様

ページの編集と削除ができる

ページにコメントできる

ページの表示ができる

11年8月16日火曜日

Page 5: 浜松Rails3道場 其の参 Controller編

Wikiの仕様

ページの編集履歴が確認できる

ユーザー認証ができる

11年8月16日火曜日

Page 6: 浜松Rails3道場 其の参 Controller編

Wikiの仕様

ページの一覧が表示できる

11年8月16日火曜日

Page 7: 浜松Rails3道場 其の参 Controller編

Wikiの仕様ページが作成できる

11年8月16日火曜日

Page 8: 浜松Rails3道場 其の参 Controller編

今回は其の参

注: ほとんどコードのコピペです

Controller編

参考 - Ruby on Rails Guides

Action Controller Overview: http://edgeguides.rubyonrails.org/action_controller_overview.html

m(_ _)m

11年8月16日火曜日

Page 9: 浜松Rails3道場 其の参 Controller編

開発環境

Ruby Version 1.9.2

Rails Version 3.0.9

.rvmrcrvm ruby-1.9.2-p180@rails-3_0_9

Rake Version 0.9.2

Up!

Up!

11年8月16日火曜日

Page 10: 浜松Rails3道場 其の参 Controller編

サンプルコードの取得GitHubから其の参前のコードを取得

git clone git://github.com/hamamatsu-rb/rails3dojo.git

git checkout -b working 2-model

前回終了時のタグ作業ブランチ

11年8月16日火曜日

Page 11: 浜松Rails3道場 其の参 Controller編

コントローラーの役割Skinny Controller, Fat Model

1)HTTPリクエストからデータを取り出す - params, request, session2)データをModelに渡して結果を受け取る3)画面表示に必要なデータを用意する - Model, flash4)結果に応じた画面を表示する - render, redirect_to

11年8月16日火曜日

Page 12: 浜松Rails3道場 其の参 Controller編

SessionsControllerログイン、ログアウトをおこなう

11年8月16日火曜日

Page 13: 浜松Rails3道場 其の参 Controller編

config/route.rb

resources :sessions

SessionsController #create #destroy

11年8月16日火曜日

Page 14: 浜松Rails3道場 其の参 Controller編

spec/controllers/sessions_controller_spec.rbdescribe "#create" do

context "ログインに成功した場合" do before do @user = create_user post :create, :user_name => @user.name, :before_path => pages_path end it "ログイン前のページにリダイレクトする" do response.should redirect_to(pages_path) end it "セッションにログインユーザーのidがセットされる" do session[:user_id].should eql(@user.id) end it "ログインユーザーの情報が取得できる" do controller.current_user.should eql(@user) end end

11年8月16日火曜日

Page 15: 浜松Rails3道場 其の参 Controller編

spec/controllers/sessions_controller_spec.rbdescribe "#create" do

context "ログインに失敗した場合" do before do @create_user post :create, :user_name => "", :before_path => root_path end it "ログイン前のページにリダイレクトする" do response.should redirect_to(root_path) end it "エラーメッセージを表示する" do flash[:error].should be end end

11年8月16日火曜日

Page 16: 浜松Rails3道場 其の参 Controller編

spec/controllers/sessions_controller_spec.rbdescribe "#create" do

context "存在しないユーザー名でログイン要求した場合" do it "ログインは成功する" do post :create, :user_name => "tom", :before_path => root_path response.should redirect_to(root_path) end it "新しいユーザーが追加される" do lambda do post :create, :user_name => "tom", :before_path => root_path end.should change(User, :count).by(1) end end

11年8月16日火曜日

Page 17: 浜松Rails3道場 其の参 Controller編

app/controllers/sessions_controller.rb

def create user = User.find_or_create_by_name(params[:user_name]) if user.valid? session[:user_id] = user.id else flash[:error] = user.errors.full_messages.first end redirect_to params[:before_path] end

11年8月16日火曜日

Page 18: 浜松Rails3道場 其の参 Controller編

app/controllers/application_controller.rb

class ApplicationController < ActionController::Base protect_from_forgery def current_user @current_user ||= User.find(session[:user_id]) if session[:user_id] @current_user rescue ActiveRecord::RecordNotFound => e nil endend

11年8月16日火曜日

Page 19: 浜松Rails3道場 其の参 Controller編

spec/controllers/sessions_controller_spec.rbdescribe "#destroy" do

before do @user = create_user session[:user_id] = @user.id delete :destroy, :id => session[:user_id], :before_path => pages_path end it "ログアウト前のページにリダイレクトする" do response.should redirect_to(pages_path) end it "セッションのuser_idがクリアされる" do session[:user_id].should_not be end it "ログインユーザーの情報は取得できない" do controller.current_user.should_not be end

11年8月16日火曜日

Page 20: 浜松Rails3道場 其の参 Controller編

app/controllers/sessions_controller.rb

def destroy session.delete(:user_id) redirect_to params[:before_path] end

11年8月16日火曜日

Page 21: 浜松Rails3道場 其の参 Controller編

PagesControllerPageの表示、作成、更新、削除

11年8月16日火曜日

Page 22: 浜松Rails3道場 其の参 Controller編

config/route.rb

resources :pages

PagesController #index #show #new #create #edit #update #delete

match ':title' => 'pages#show', :via => [:get], :as => :wiki_page

11年8月16日火曜日

Page 23: 浜松Rails3道場 其の参 Controller編

spec/controllers/pages_controller_spec.rb

describe "#index" do before do create_page(:user => create_page.user) get :index end it "テンプレートindexを表示する" do response.should render_template(:index) end

it "最新のPageのリストを表示する" do pages = assigns(:pages) pages.first.created_at.should > pages.last.created_at end end

11年8月16日火曜日

Page 24: 浜松Rails3道場 其の参 Controller編

app/controllers/pages_controller.rb

def index @pages = Page.recent end

11年8月16日火曜日

Page 25: 浜松Rails3道場 其の参 Controller編

spec/controllers/pages_controller_spec.rb

describe "#show" do

it "GET wiki_page_path(title)にマッチ" do { :get => wiki_page_path(:title => "Home") }.should \ route_to("pages#show", :title => "Home") end

11年8月16日火曜日

Page 26: 浜松Rails3道場 其の参 Controller編

spec/controllers/pages_controller_spec.rb

describe "#show" do

context "Pageが存在する場合" do before do @page = create_page get :show, :title => @page.title end it "テンプレートshowを表示する" do response.should render_template(:show) end it "タイトルが一致するPageを表示する" do assigns(:page).title.should eql(@page.title) end end

11年8月16日火曜日

Page 27: 浜松Rails3道場 其の参 Controller編

spec/controllers/pages_controller_spec.rb

describe "#show" do context "Pageが存在しない場合" do before do get :show, :title => "New Page" end it "テンプレートnewを表示する" do response.should render_template(:new) end it "タイトルは入力済み" do assigns(:page).title.should eql("New Page") end it "未作成Pageメッセージを表示する" do flash[:notice].should be end end

11年8月16日火曜日

Page 28: 浜松Rails3道場 其の参 Controller編

app/controllers/pages_controller.rb

def show @page = Page.find_by_title(params[:title]) unless @page flash.now[:notice] = "Page was not created yet." @page = Page.new(:title => params[:title]) render :action => :new end end

11年8月16日火曜日

Page 29: 浜松Rails3道場 其の参 Controller編

spec/controllers/pages_controller_spec.rb

describe "#new" do

context "ログインしていない場合" do before do request.env['HTTP_REFERER'] = pages_url get :new end it "元いたページにリダイレクトする" do response.should redirect_to(pages_url) end it "ログイン要求メッセージを表示する" do flash[:error].should be end end

11年8月16日火曜日

Page 30: 浜松Rails3道場 其の参 Controller編

app/controllers/application_controller.rb

class ApplicationController < ActionController::Base protect_from_forgery def current_user @current_user ||= User.find(session[:user_id]) if session[:user_id] @current_user rescue ActiveRecord::RecordNotFound => e nil end def login_required unless current_user flash[:error] = "This action is login required." url = request.env['HTTP_REFERER'] || root_url redirect_to url end endend

11年8月16日火曜日

Page 31: 浜松Rails3道場 其の参 Controller編

app/controllers/pages_controller.rb

before_filter :login_required, :except => [:index, :show]

11年8月16日火曜日

Page 32: 浜松Rails3道場 其の参 Controller編

spec/spec_helper.rb

def login(user_name = nil) user = user_name ? create_user(:name => user_name) : create_user session[:user_id] = user.idend

def logout controller.instance_variable_set("@current_user", nil) session.delete(:user_id)end

def filtered_by_login_required url = request.env['HTTP_REFERER'] || root_url response.should redirect_to(url) flash[:error].should beend

11年8月16日火曜日

Page 33: 浜松Rails3道場 其の参 Controller編

spec/controllers/pages_controller_spec.rb

describe "#new" do

context "ログイン済みの場合" do before do login get :new end it "テンプレートnewを表示する" do response.should render_template(:new) end it "新規Page作成フォームを表示する" do assigns(:page).should be_new_record end end end

11年8月16日火曜日

Page 34: 浜松Rails3道場 其の参 Controller編

app/controllers/pages_controller.rb

def new @page = Page.new end

11年8月16日火曜日

Page 35: 浜松Rails3道場 其の参 Controller編

spec/controllers/pages_controller_spec.rb describe "#create" do

context "正しいデータが送信された場合" do before do @before_count = Page.count post :create, :page => { :title => "New Page" } end it "Wikiページにリダイレクトする" do response.should redirect_to(wiki_page_path("New Page")) end it "成功メッセージが表示される" do flash[:notice].should be end it "新しいPageが作成される" do Page.count.should eql(@before_count + 1) end end

11年8月16日火曜日

Page 36: 浜松Rails3道場 其の参 Controller編

spec/controllers/pages_controller_spec.rb

describe "#create" do context "不正なデータが送信された場合" do before do post :create, :page => { :title => "" } end it "テンプレートnewを表示する" do response.should render_template(:new) end it "入力エラーメッセージを表示する" do flash[:error].should be end end

11年8月16日火曜日

Page 37: 浜松Rails3道場 其の参 Controller編

app/controllers/pages_controller.rb

def create @page = Page.new(params[:page]) @page.user = current_user if @page.save flash[:notice] = "Page was created." redirect_to wiki_page_path(@page.title) else flash.now[:error] = "Page could not create." render :action => :new end end

11年8月16日火曜日

Page 38: 浜松Rails3道場 其の参 Controller編

spec/controllers/pages_controller_spec.rb

describe "#edit" do

context "Pageが存在する場合" do before do @page = create_page(:user => controller.current_user) get :edit, :id => @page.id end it "テンプレートeditを表示する" do response.should render_template(:edit) end

it "Page編集フォームを表示する" do assigns(:page).should_not be_new_record end end

11年8月16日火曜日

Page 39: 浜松Rails3道場 其の参 Controller編

spec/controllers/pages_controller_spec.rb

describe "#edit" do

context "Pageが存在しない場合" do it "例外RecordNotFoundを投げる" do lambda do get :edit, :id => 99999 end.should raise_error(ActiveRecord::RecordNotFound) end end

11年8月16日火曜日

Page 40: 浜松Rails3道場 其の参 Controller編

app/controllers/pages_controller.rb

def edit @page = Page.find(params[:id]) end

11年8月16日火曜日

Page 41: 浜松Rails3道場 其の参 Controller編

spec/controllers/pages_controller_spec.rb

describe "#update" do context "正しいデータが送信された場合" do before do @page = create_page(:user => controller.current_user) @before_histries_count = @page.histories.count put :update, :id => @page.id, :page => { :title => "New Title" } end it "Wikiページにリダイレクトする" do response.should redirect_to(wiki_page_path("New Title")) end it "成功メッセージが表示される" do flash[:notice].should be end it "Pageが更新される" do assigns(:page).should be_valid assigns(:page).title.should eql("New Title") end it "Historyが追加される" do assigns(:page).histories.count.should eql(@before_histries_count + 1) end end

11年8月16日火曜日

Page 42: 浜松Rails3道場 其の参 Controller編

spec/controllers/pages_controller_spec.rb

describe "#update" do

context "不正なデータが送信された場合" do before do @page = create_page(:user => controller.current_user) put :update, :id => @page.id, :page => { :title => "" } end it "テンプレートeditを表示する" do response.should render_template(:edit) end it "入力エラーメッセージを表示する" do flash[:error].should be end end

11年8月16日火曜日

Page 43: 浜松Rails3道場 其の参 Controller編

app/controllers/pages_controller.rb

def update @page = Page.find(params[:id]) @page.attributes = params[:page] if @page.save_by_user(current_user) flash[:notice] = "Page was updated." redirect_to wiki_page_path(@page.title) else flash.now[:error] = "Page could not update." render :action => :edit end end

11年8月16日火曜日

Page 44: 浜松Rails3道場 其の参 Controller編

spec/controllers/pages_controller_spec.rb describe "#destroy" do

context "Pageが存在する場合" do before do @page = create_page(:user => controller.current_user) @before_count = Page.count put :destroy, :id => @page.id end it "Homeにリダイレクトする" do response.should redirect_to(root_path) end it "成功メッセージを表示する" do flash[:notice].should be end it "Pageが削除される" do Page.count.should eql(@before_count - 1) end end

11年8月16日火曜日

Page 45: 浜松Rails3道場 其の参 Controller編

app/controllers/pages_controller.rb

def destroy @page = Page.find(params[:id]) @page.destroy flash[:notice] = "Page was deleted." redirect_to root_path end

11年8月16日火曜日

Page 46: 浜松Rails3道場 其の参 Controller編

CommentsControllerCommentの作成、削除

11年8月16日火曜日

Page 47: 浜松Rails3道場 其の参 Controller編

config/route.rb

CommentsController #create #delete

resources :pages do resources :comments end

11年8月16日火曜日

Page 48: 浜松Rails3道場 其の参 Controller編

spec/controllers/comments_controller_spec.rb describe "#create" do

context "コメントが入力されている場合" do before do post :create, :page_id => @page.id, \ :comment => { :body => "Comment...." } end it "Wikiページにリダイレクトする" do response.should \ redirect_to(wiki_page_path(:title => @page.title)) end it "成功メッセージを表示する" do flash[:notice].should be end it "Commentが追加される" do assigns(:page).comments.count.should eql(@before_count + 1) end end

11年8月16日火曜日

Page 49: 浜松Rails3道場 其の参 Controller編

spec/controllers/comments_controller_spec.rb

describe "#create" do

context "コメントが入力されていない場合" do before do post :create, :page_id => @page.id, \ :comment => { :body => "" } end it "Wikiページにリダイレクトする" do response.should \ redirect_to(wiki_page_path(:title => @page.title)) end it "エラーメッセージを表示する" do flash[:error].should be end end

11年8月16日火曜日

Page 50: 浜松Rails3道場 其の参 Controller編

app/controllers/comments_controller.rb

before_filter :login_required def create @page = Page.find(params[:page_id]) @comment = @page.comments.build(params[:comment]) @comment.user = current_user if @comment.save flash[:notice] = "Comment was created." else flash[:error] = "Comment could not create." end redirect_to wiki_page_path(:title => @page.title) end

11年8月16日火曜日

Page 51: 浜松Rails3道場 其の参 Controller編

spec/controllers/comments_controller_spec.rb

describe "#destroy" do

context "データを正しく指定した場合" do before do delete :destroy, :page_id => @page.id, :id => @comment.id end it "Wikiページにリダイレクトする" do response.should \ redirect_to(wiki_page_path(:title => @page.title)) end it "成功メッセージを表示する" do flash[:notice].should be end

it "コメントが削除される" do assigns(:page).comments.count.should eql(@before_count - 1) end end

11年8月16日火曜日

Page 52: 浜松Rails3道場 其の参 Controller編

spec/controllers/comments_controller_spec.rb

describe "#destroy" do context "データが存在しない場合" do it "例外RecordNotFoundを投げる" do lambda do delete :destroy, :page_id => 999, :id => @comment.id end.should raise_error(ActiveRecord::RecordNotFound) lambda do delete :destroy, :page_id => @page.id, :id => 999 end.should raise_error(ActiveRecord::RecordNotFound) end end

11年8月16日火曜日

Page 53: 浜松Rails3道場 其の参 Controller編

app/controllers/comments_controller.rb

def destroy @page = Page.find(params[:page_id]) @comment = @page.comments.find(params[:id]) @comment.destroy flash[:notice] = "Comment was deleted." redirect_to wiki_page_path(:title => @page.title) end

11年8月16日火曜日

Page 54: 浜松Rails3道場 其の参 Controller編

WelcomeControllerトップページの表示

11年8月16日火曜日

Page 55: 浜松Rails3道場 其の参 Controller編

config/route.rb

WelcomeController #index

root :to => "welcome#index"

11年8月16日火曜日

Page 56: 浜松Rails3道場 其の参 Controller編

spec/controllers/welcome_controller_spec.rb

describe "#index" do context "'Home'というタイトルのPageが存在する場合" do before do home = create_page(:title => "Home") create_page(:title => "Other", :user => home.user) get :index end it "テンプレート pages/show を表示する" do response.should render_template('pages/show') end it "'Home'を表示する" do assigns(:page).title.should eql("Home") end end

11年8月16日火曜日

Page 57: 浜松Rails3道場 其の参 Controller編

spec/controllers/welcome_controller_spec.rb

describe "#index" do

context "Page 'Home'が存在しない場合" do before do home = create_page(:title => "Other") get :index end it "テンプレート index を表示する" do response.should render_template(:index) end it "Pageはアサインされない" do assigns(:page).should_not be end end

11年8月16日火曜日

Page 58: 浜松Rails3道場 其の参 Controller編

app/controllers/welcome_controller.rb

class WelcomeController < ApplicationController def index @page = Page.find_by_title("Home") render :template => 'pages/show' if @page endend

11年8月16日火曜日

Page 59: 浜松Rails3道場 其の参 Controller編

今回の開発はここまで

git checkout 3-controller

作業内容をmasterにマージgit checkout mastergit merge working

作業後のコードはGitHubにありますgit clone git://github.com/hamamatsu-rb/rails3dojo.git

git branch -d working

11年8月16日火曜日

Page 60: 浜松Rails3道場 其の参 Controller編

Q&A

11年8月16日火曜日

Page 61: 浜松Rails3道場 其の参 Controller編

多分、ActionView

次回予告

11年8月16日火曜日