Upload
masakuni-kato
View
3.408
Download
1
Embed Size (px)
DESCRIPTION
2011/08/10のHamamatsu.rb#6で使った資料です。
Citation preview
浜松Rails3道場其の参 Controller編
Hamamatsurb#5 2011.08.10 @mackato
11年8月16日火曜日
浜松Rails3道場の心得
習うより慣れろ
理論より実用
未知を恐れない
11年8月16日火曜日
実際にRailsアプリを作ってみる
Wiki
全5回位で
11年8月16日火曜日
Wikiの仕様
ページの編集と削除ができる
ページにコメントできる
ページの表示ができる
11年8月16日火曜日
Wikiの仕様
ページの編集履歴が確認できる
ユーザー認証ができる
11年8月16日火曜日
Wikiの仕様
ページの一覧が表示できる
11年8月16日火曜日
Wikiの仕様ページが作成できる
11年8月16日火曜日
今回は其の参
注: ほとんどコードのコピペです
Controller編
参考 - Ruby on Rails Guides
Action Controller Overview: http://edgeguides.rubyonrails.org/action_controller_overview.html
m(_ _)m
11年8月16日火曜日
開発環境
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日火曜日
サンプルコードの取得GitHubから其の参前のコードを取得
git clone git://github.com/hamamatsu-rb/rails3dojo.git
git checkout -b working 2-model
前回終了時のタグ作業ブランチ
11年8月16日火曜日
コントローラーの役割Skinny Controller, Fat Model
1)HTTPリクエストからデータを取り出す - params, request, session2)データをModelに渡して結果を受け取る3)画面表示に必要なデータを用意する - Model, flash4)結果に応じた画面を表示する - render, redirect_to
11年8月16日火曜日
SessionsControllerログイン、ログアウトをおこなう
11年8月16日火曜日
config/route.rb
resources :sessions
SessionsController #create #destroy
11年8月16日火曜日
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日火曜日
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日火曜日
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日火曜日
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日火曜日
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日火曜日
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日火曜日
app/controllers/sessions_controller.rb
def destroy session.delete(:user_id) redirect_to params[:before_path] end
11年8月16日火曜日
PagesControllerPageの表示、作成、更新、削除
11年8月16日火曜日
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日火曜日
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日火曜日
app/controllers/pages_controller.rb
def index @pages = Page.recent end
11年8月16日火曜日
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日火曜日
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日火曜日
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日火曜日
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日火曜日
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日火曜日
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日火曜日
app/controllers/pages_controller.rb
before_filter :login_required, :except => [:index, :show]
11年8月16日火曜日
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日火曜日
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日火曜日
app/controllers/pages_controller.rb
def new @page = Page.new end
11年8月16日火曜日
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日火曜日
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日火曜日
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日火曜日
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日火曜日
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日火曜日
app/controllers/pages_controller.rb
def edit @page = Page.find(params[:id]) end
11年8月16日火曜日
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日火曜日
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日火曜日
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日火曜日
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日火曜日
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日火曜日
CommentsControllerCommentの作成、削除
11年8月16日火曜日
config/route.rb
CommentsController #create #delete
resources :pages do resources :comments end
11年8月16日火曜日
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日火曜日
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日火曜日
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日火曜日
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日火曜日
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日火曜日
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日火曜日
WelcomeControllerトップページの表示
11年8月16日火曜日
config/route.rb
WelcomeController #index
root :to => "welcome#index"
11年8月16日火曜日
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日火曜日
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日火曜日
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日火曜日
今回の開発はここまで
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日火曜日
Q&A
11年8月16日火曜日
多分、ActionView
次回予告
11年8月16日火曜日