418342 ภาคปลาย 2552/การบ้าน 3

จาก Theory Wiki
ไปยังการนำทาง ไปยังการค้นหา

(กำลังเขียนอยู่)​ ในการบ้านนี้เราจะทำการสร้างระบบบล็อกเบื้องต้นที่มีฟีเจอร์ดังต่อไปนี้

  • มีหน้าหลักแสดงโพสต์ล่าสุด
  • มีระบบให้ผู้อ่านมาพิมพ์คอมเมนต์
  • มี RSS Feed ของโพสต์
  • ผู้เขียนสามารถตั้งค่าต่างๆ ของบล็อก เช่น ชื่อบล็อก, จำนวนโพสต์ที่แสดงในแต่ละหน้า, ฯลฯ
  • ผู้เขียนสามารถแท็กบทความต่างๆ ได้

เริ่มต้น

  • ให้ดาวน์โหลดโค้ดเริ่มต้นจาก ... ในโค้ดเริ่มต้นนี้จะมี scaffold ซึ่งสร้างตามฐานข้อมูลที่เขียนไว้ข้างล่าง พร้อมกับข้อมูลทดสอบส่วนหนึ่งอยู่
  • ให้ลงไลบรารี Maruku ซึ่งเป็นตัวแปรภาษา Makrdown ที่เราจะใช้ในการเขียนเนื้อหาของบล็อก ด้วยการสั่ง
gem install maruku

ฐานข้อมูล

ฐานข้อมูลของระบบบล็อกจะประกอบด้วยตารางต่อไปนี้

ตาราง posts

เก็บโพสต์ของเจ้าของบล็อก มีฟีลด์ดังต่อไปนี้

  • title เป็น string
  • content เป็น text ซึ่งเขียนด้วยภาษา Markdown
  • published_at เป็น datetime ซึ่งจะมีค่าเป็น nil ถ้าหากผู้ใช้ยังไม่ได้ตีพิมพ์โพสต์นี้
  • timestamp (created_at และ modified_at) ซึ่งสร้างด้วย t.timestamp ใน migration

ตาราง comments

เก็บคอมเมนต์ที่มีคนมาเขียน มีฟีลด์ดังต่อไปนี้

  • name เป็น string เก็บชื่อคนเขียน comment
  • email เป็น string เก็บ email ของคนเขียน comment
  • url เป็น string เก็บ URL ของเว็บไซต์ของคนเขียน comment
  • content เป็น text ซึ่งเขียนด้วยภาษา Markdown เช่นกัน
  • post_id เป็น integer ซึ่งเก็บ id ของ post ที่ comment
  • timestamp (created_at และ modified_at) ซึ่งสร้างด้วย t.timestamp ใน migration

ตาราง tags

เก็็บ tag ต่างๆ มีฟีลด์ดังต่อไปนี้

  • name เป็น string ซึ่งเป็นชื่อของ tag

ตาราง posts_tags

ใช้ในการทำความสัมพันธ์แบบ many-to-many ระหว่าง post กับ tag มีฟีลด์ดังต่อไปนี้

  • post_id
  • tag_id

ตาราง settings

เก็บค่าต่างๆ ที่ผู้ใช้สามารถกำหนดให้บล็อกได้ เช่น ชื่อบล็อก ฯลฯ มีฟีลด์ดังต่อไปนี้

  • name เป็น string ซึ่งเป็นชื่อของค่าที่ผู้ใช้กำหนดได้
  • value เป็น string ซึ่งเก็บค่าจริง

ในตาราง settings จะมีค่าต่อไปนี้อยู่

  • blog_name = ชื่อของบล็อก (จะปรากฏอยู่ที่หัวเว็บเพจ)
  • blog_subtitle = คำอธิบายบล็อกสั้นๆ (จะปรากฏอยู่ที่หัวเว็บเพจเช่นกัน)
  • blog_url = URL ของบล็อกซึ่งมีไว้ใช้ทำ RSS feed
  • posts_per_page = จำนวนบล็อกในแต่ละหน้า
  • comment_count = จำนวนคอมเมนต์เริ่มต้นที่แสดงเวลาดูโพสต์

การบ้านข้อ 1: แก้ไขโมเดล

แก้ไข Post

  1. ทำให้ Post มีความสัมพันธ์แบบ many-to-many กับ Tag
  2. ทำให้ Post มีความสัมพันธ์แบบ many-to-one กับ Comment
  3. เขียน validation ทำให้ Post สอดคล้องกับเงื่อนไขต่อไปนี้
    • title จะต้องไม่ว่างเปล่า
    • content จะต้องไม่ว่างเปล่า
  4. เขียนเมธอดชื่อ published? เพื่อเช็คว่าผู้ใช้ได้ตีพิมพ์โพสต์ไปแล้วหรือยัง โดย method จะเช็คว่า published_at มีค่าเป็น nil หรือไม่ ถ้าใช่แสดงว่ายังไม่ได้ตีพิมพ์

เมื่อคุณแก้โค้ดตามนี้แล้ว ให้ลองรัน

rake test:units TEST=unit/test/post_test.rb

เพื่อตรวจสอบว่าได้แก้ไขไปถูกต้องแล้วหรือไม่

แก้ไข Comment

เขียน validation ทำให้ Comment สอดคล้องกับเงื่อนไขต่อไปนี้

  • name จะต้องไม่ว่างเปล่า
  • email จะต้องมีรูปแบบเหมือน email ​(ใบ้: ใช้ validate_format_of)
  • url จะต้องมีรูปแบบเหมือน URL จริงๆ (คือ http://something.someone.org/abc/def) (ใบ้: ไปหา regular expression มาจากใน net)
  • content จะต้องไม่ว่างเปล่า

เมื่อคุณแก้โค้ดตามนี้แล้ว ให้ลองรัน

rake test:units TEST=unit/test/comment_test.rb

เพื่อตรวจสอบว่าได้แก้ไขไปถูกต้องแล้วหรือไม่

แก้ไข Tag

เขียน validation

ทำให้ Tag ที่มีรูปแบบถูกต้องทุกตัวสอดคล้องกับเงื่อนไขต่อไปนี้

  • name จะต้องไม่ว่างเปล่า
  • ใน name จะต้องไม่มีเครื่องหมายคอมมา (,) อยู่ภายใน (เนื่องจากเราใจใช้เครื่องหมายนี้ในการแยก tag ต่างๆ ออกจากกัน) กล่าวคือ "space adventure" ใช้ได้แต่ "space,adventure" หรือ "space, adventure" ใช้ไม่ได้

ทำให้ชื่อ Tag อยู่ในรูป "ปกติ"

เราต้องการให้เวลาเจ้าของบล็อกใส่ tag ให้โพสต์ แล้วเขาสามารถพิมพ์ "life, space adventure, computer   security " แล้วระบบสามารถที่จะแยกมันออกเป็น 3 tag ได้แก่ "life", "space adventure", และ "computer security" ให้โดยอัตโนมัติ

เนื่องจากเราบอกว่าชื่อแท็กจะต้องไม่มีเครื่องหมายคอมมาอยู่ข้างใน ดังนั้นเราสามารถแยก string ที่ผู้ใช้ให้มาข้างบนเป็นสามส่วนคือ "life" และ " space adventure" และ " computer   security "

เวลาเราเก็บชื่อของ Tag ใน database เราต้องการกำจัดข้อมูลที่ไม่สำคัญออกจากชื่อ Tag ที่ผู้ใช้ป้อนมาไป ยกตัวอย่างเช่น ผู้ใช้ป้อน " computer   security " ซึ่งมีช่องว่างอยู่ข้างหน้าชื่อ ข้างหลังชื่อ และช่องว่างระหว่างคำว่า computer กับคำว่า security มีอยู่ถึงสามตัว แต่ในเวลาเก็บข้อมูลเราต้องการให้ชื่อมีค่าเท่ากับ "computer security" เท่านั้น กล่าวคือ

  • จะต้องไม่มีช่องว่างนำหน้าชื่อ Tag
  • จะต้องไม่มีช่องว่างตามหลังชื่อ Tag
  • ระหว่างคำสองคำที่อยู่ข้างๆ กันในชื่อ Tag จะมีช่องว่างคั่นได้เพียงช่องเดียวเท่านั้น

เราเรียกชื่อที่สอดคล้องกับกฎทั้งสามข้อข้างต้นว่าเป็นชื่อ Tag ในรูป "ปกติ"

ตรวจสอบความถูกต้อง

จงเพิ่มเมธอด name=(given_name) ใน Tag โดยที่เมธอดนี้ทำหน้าที่เซตค่า name ของโมเดลใหม่ ให้มีค่าเท่ากับค่าของ given_name เมื่อทำให้มันอยู่ในรูปปกติ

เมื่อคุณแก้โค้ดตามนี้แล้ว ให้ลองรัน

rake test:units TEST=unit/test/tag_test.rb

เพื่อตรวจสอบว่าได้แก้ไขไปถูกต้องแล้วหรือไม่

แก้ไข Setting

จงเขียน validation เพื่อทำให้ Setting ทุกตัวสอดคล้องกับเงื่อนไขต่อไปนี้