Rails勉強会@関西6 初心者レッスン発展課題の解答例
発展課題の解答を用意してみました。
一解答例にすぎませんが、参考にしてください。
急いで作ったので間違ってたらツッコんでください。
:per_page に指定した数字に合わせて、前のン件, 次のン件としてみよう。
ActionController::Pagination::Paginator#items_per_pageを使って、
$ vi app/views/bbs/list.rhtml
<%= link_to "前の#{@comment_pages.items_per_page}件", { :page => @comment_pages.current.previous }
if @comment_pages.current.previous %>
<%= link_to "次の#{@comment_pages.items_per_page}件", { :page => @comment_pages.current.next }
if @comment_pages.current.next %>リファレンスマニュアルでは、Attributesのところにあって、なんの説明もないので、見つけにくいかもしれません。
http://localhost:3000/bbs/edit/1 と言う風に直接アクセスすると、誰の発言でも自由に編集できてしまう。コントローラから使ってないメソッドを削除して、編集ができないようにしよう。
app/controllers/bbs_controller.rb中の、edit,show,updateメソッドを削除し、verify の行にある、:updateも消す。
app/views/bbs/edit.rhtmlとapp/views/bbs/show.rhtml二つのファイルも消します。
投稿フォームを /list/bbs の一番上に移動して、直接投稿できるようにしてみよう。
app/views/bbs/list.rhtmlの上の方に、
<div>
<%= start_form_tag :action => 'create' %>
<%= render :partial => 'form' %>
<%= submit_tag "投稿" %>
<%= end_form_tag %>
</div>を追加。
# app/controllers/bbs_controller.rb
def list
@comment_pages, @comments = paginate :comments, :per_page => 10, :order => 'created_at desc'
@comment ||= Comment.new # ||= は、create から呼ばれた時に@commentを上書きしないため。
end
def create
@comment = Comment.new(params[:comment])
if @comment.save
flash[:notice] = 'Comment was successfully created.'
redirect_to :action => 'list'
else
list # この行追加
render :action => 'list' # エラーがあった場合の戻り先を変更
end
end
# new アクションは削除app/views/bbs/new.rhtmlも消してしまいましょう。
Commentにvalidatesを追加して、必須項目を決めよう。
title, body, name を必須項目に、email, homapage は空じゃなかったら、正規表現で判定をしています。 email の方の正規表現は、 validates_format_of のサンプルコードから、homepageの方は先頭がhttp://またはhttps://かをチェックしています。 凝りたい人はどうぞ。
# app/models/comment.rb
class Comment < ActiveRecord::Base
validates_presence_of [:title, :body, :name]
validates_format_of :email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, :if => proc{|comment| !comment.email.blank?}
validates_format_of :homepage, :with => %r|^https?://|, :if => proc{|comment| !comment.homepage.blank?}
endまた、次のようなテストコードを書いて、
$ rake test:units
を実行することで、正しそうに動いているかチェックできます。
テストコード↓を書いてから、実装↑を書くと、TDD.
# test/unit/comment_test.rb
require File.dirname(__FILE__) + '/../test_helper'
class CommentTest < Test::Unit::TestCase
def setup
@comment = Comment.new(:title => 'hi!', :body => 'hello!', :name => 'bob', :email => "", :homepage => "")
end
def test_validation
assert_valid @comment
end
def test_presence_on_title
@comment.title = nil
@comment.save
assert_not_nil @comment.errors.on(:title)
end
def test_presence_on_body
@comment.body = nil
@comment.save
assert_not_nil @comment.errors.on(:body)
end
def test_presence_on_name
@comment.name = nil
@comment.save
assert_not_nil @comment.errors.on(:name)
end
def test_email
@comment.email = 'bob@rails6.com'
@comment.save
assert_valid @comment
@comment.email = 'bob.rails6.com'
@comment.save
assert_not_nil @comment.errors.on(:email)
end
def test_homepage
@comment.homepage = 'https://bob.rails6.com'
@comment.save
assert_valid @comment
@comment.homepage = 'http://bob.rails6.com'
@comment.save
assert_valid @comment
@comment.homepage = 'ftp://bob.rails6.com'
@comment.save
assert_not_nil @comment.errors.on(:homepage)
end
end削除キーを入力しないと削除できないようにしてみよう。
まず、migration でdelete_key というカラムを追加します。
$ script/generate migration AddDeleteKey
exists db/migrate
create db/migrate/004_add_delete_key.rb# vi db/migrate/004_add_delete_key.rb
class AddDeleteKey < ActiveRecord::Migration
def self.up
add_column :comments, :delete_key, :string
end
def self.down
remove_column :comments, :delete_key
end
end$ rake db:migrate
次に、投稿フォームに、削除キー入力フィールドを作り、
<!-- app/views/bbs/_form.rhtml -->
<p><label for="comment_delete_key">削除キー</label><br/>
<%= text_field 'comment', 'delete_key' %></p>削除ボタンのとなりにテキストフィールドを追加。
<!-- app/views/bbs/list.rhtml -->
<td>投稿日時:<%= comment.created_at.strftime("%Y/%m/%d %H:%M:%S") %></td>
<td>
<%= start_form_tag :action => 'destroy', :id => comment %>
<%= text_field_tag 'delete_key' %>
<%= submit_tag "削除" %>
<%= end_form_tag %>
</td>その値を受けて、保存された削除キーと、入力された削除キーが一致しないとdestroyしないように、コントローラを書き換える。
# app/controllers/bbs_controller.rb
def destroy
c = Comment.find(params[:id])
c.destroy if !c.delete_key.blank? && c.delete_key == params[:delete_key]
redirect_to :action => 'list'
end今回のテストコードは、コントローラのテストなので、以下の通り。
まず、テストデータを二つ用意。 片方は、削除キー’bob123’、片方は削除キーなし(削除できない)
# test/fixtures/comments.rb
bob:
id: 1
title: hi
body: hello
name: bob
delete_key: bob123
undeletable:
id: 2
title: hi
body: hello
name: bob
delete_key: ''# test/functional/bbs_controller_test.rb
require File.dirname(__FILE__) + '/../test_helper'
require 'bbs_controller'
# Re-raise errors caught by the controller.
class BbsController; def rescue_action(e) raise e end; end
class BbsControllerTest < Test::Unit::TestCase
# テスト用データである、fixture をロード。(上で書いたやつ)
fixtures :comments
# test_* の前に実行される。
def setup
@controller = BbsController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
end
# 削除キーを指定しないと削除されない
def test_destroy_without_delete_key
id = comments(:bob).id
assert_not_nil Comment.find(id)
post :destroy, :id => id
assert_not_nil Comment.find(id)
end
# 削除キーを指定すると削除される
def test_destroy_with_delete_key
id = comments(:bob).id
assert_not_nil Comment.find(id)
post :destroy, :id => id, :delete_key => comments(:bob).delete_key
assert_raise(ActiveRecord::RecordNotFound) {
Comment.find(id)
}
end
# 削除キーが空のレコードは、空の削除キーで削除できない
def test_destroy_record_having_empty_delete_key
id = comments(:undeletable).id
assert_not_nil Comment.find(id)
post :destroy, :id => id, :delete_key => comments(:undeletable).delete_key
assert_not_nil Comment.find(id)
end
end10 comments »
-
By ばば 25/01/2007 at 00h14
-
By Etenuesty 22/06/2011 at 22h50
Hi great post we have going here! Mars Venus Coaching
-
By steathesolley 24/06/2011 at 20h54
im prospering to this passage fetich called a friday fest with my cocker tonight and idk what it is,there like stands and building blocks, but if u advised of, plz disbosom oneself me so i can have a good shilly-shally!!! lol -THANKS!! :)
-
By invoizict 16/07/2011 at 10h54
moral gonna phrase hello…
-
By osteomitummaf 25/11/2011 at 12h38
-
By osteomitummaf 25/11/2011 at 12h38
-
By osteomitummaf 25/11/2011 at 12h38
-
By osteomitummaf 25/11/2011 at 12h38
-
By NoobleeSM 29/11/2011 at 13h46
Hi everyone!
The most beautiful women in the world, you must see.
Free adult webcam: click here -
By zinassswerzz 05/01/2012 at 07h28
Люди!!! Я нашла уникальный метод, с помощью которого я полностью излечила своего мужа от АЛКОГОЛИЗМА (!) История моя длинная, не стану тут её полностью описывать, а кому интересно - добро пожаловать на мою страницу, где я всё подробно рассказываю: http://t1234.ru/index-nat.htm !
レッスンお疲れ様でした! ちゃんとフォローが!!!m( )m ありがたく、メモさせてもらいます^^;