The document discusses the development of a wiki application using Ruby on Rails. It goes through setting up controllers and specs for user authentication including login, logout, and authorization. It then covers controllers and specs for pages including indexing, showing, creating, editing, updating, and deleting pages. Finally, it mentions setting up comments as a nested resource of pages.
14. spec/controllers/sessions_controller_spec.rb
describe "#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
15. spec/controllers/sessions_controller_spec.rb
describe "#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
16. spec/controllers/sessions_controller_spec.rb
describe "#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
17. 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
18. 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
end
11 8 16
19. spec/controllers/sessions_controller_spec.rb
describe "#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
23. 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
25. 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
26. 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
27. 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
28. 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
29. 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
30. 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
end
end
11 8 16
32. spec/spec_helper.rb
def login(user_name = nil)
user = user_name ? create_user(:name => user_name) : create_user
session[:user_id] = user.id
end
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 be
end
11 8 16
33. 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
35. 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
36. 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
37. 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
38. 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
39. 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
41. 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
42. 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
43. 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
44. 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
45. 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
47. config/route.rb
resources :pages do
resources :comments
end
CommentsController
#create
#delete
11 8 16
48. 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
49. 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
50. 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
51. 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
52. 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
56. 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
57. 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
58. app/controllers/welcome_controller.rb
class WelcomeController < ApplicationController
def index
@page = Page.find_by_title("Home")
render :template => 'pages/show' if @page
end
end
11 8 16
59. git checkout master
git merge working
git branch -d working
git clone git://github.com/hamamatsu-rb/rails3dojo.git
git checkout 3-controller
11 8 16