การ preprocess อินพุตจาก view ก่อนเอาใส่ database ใน rails

  • warning: realpath() [function.realpath]: SAFE MODE Restriction in effect. The script whose uid is 1005 is not allowed to access /tmp owned by uid 0 in /var/www/sites/sugree/codenone.com/subdomains/www/html/includes/file.inc on line 190.
  • warning: realpath() [function.realpath]: SAFE MODE Restriction in effect. The script whose uid is 1005 is not allowed to access /tmp owned by uid 0 in /var/www/sites/sugree/codenone.com/subdomains/www/html/includes/file.inc on line 190.

เผอิญเพิ่งหัดเล่นน่ะครับ มีคำถามเกี่ยวกับการจัดการว่าอะไรทำอะไรใน MVC น่ะครับ

คือ ผมอยากมีหน้า edit ที่ผู้ใช้จะป้อนกระทู้ ในกระทู้เนี่ยะมีหลายย่อหน้า ทีนี้ ก่อนจะเก็บเข้า database ผมอยากจะ process มันเสียก่อน โดยจะแยกแต่ละย่อหน้าออกเป็นหลาย ๆ แถวในตารางน่ะครับ (ให้นึกถึง wikipedia นะครับ)

ทีนี้ ถ้าทำตาม MVC ตามที่ผมเข้าใจ ในโมเดลผมอาจจะต้องมี Post แล้วก็ Paragraph แล้ว Post มีหลาย paragraph แต่ทีนี้ เวลารับข้อมูลมาจาก view มันจะเอาเข้ามายังไงน่ะครับ

ไม่ทราบใครพอมีไอเดียอะไรแนะนำหรือเปล่าครับ?

สมมติ view เรามีหน้้าตาแบบนี้

<%= start_form_tag(:action=>'post') %>
<input type='text' name='name'/>
<textarea name='mypost' cols='40' rows='5'></textarea>
<input type='submit'/>
<%= end_form_tag %>

ให้ model มี attributes ดังนี้

Post
 + name
Paragraph
 + content

controller เราก็หน้าตาประมาณนี้

  def post
    post = Post.new(:name => params[:name])
    params[:mypost].split().each do |para|
      p = Paragraph.new(:content => para)
      post.paragraphs << p
    end
    post.save
    redirect_to :action => 'index'
  end


แต่ถ้าแยก logic ออกจาก controller ก็อาจจะทำแบบนี้แทน

class Paragraph < ActiveRecord::Base
  belongs_to :post
 
  def self.parse(text)
    text.split().map do |p|
      Paragraph.new(:content => p)
    end
  end
 
end

แล้วก็เรียกใช้แบบนี้

  def post
    post = Post.new(:name => params[:name])
    post.paragraphs = Paragraph.parse(params[:mypost])
    post.save
    render :action => 'index'
  end

โอ้ว อันหลังเจ๋งมากครับ

ขอบคุณมากครับ

apirak's picture

จริงๆ ตามทฤษฏี MVC แล้ว เราควรเอาการตัด Paragraph ไปไว้ที่ controller หรือ model

ไม่รู้ว่ามีหลักในการพิจารณาอย่างไร??

Apirak

ผมเลือกเอาจากความไกล้นะ
อย่าง สมมติต้องมีแปลง datatype ก่อนเก็บลง model
(ตัวอย่างของ java, เพราะ ruby เป็น dynamic type)
ผมเลือกให้ code อยู่ใน controller

กรณี split paragraph นี้
การ split paragraph จาก long text ยาวๆ
มันก้ำกึ่ง, จะว่าอยู่ไกล้ view ก็ฟังขึ้น
จะว่าอยู่ไกล้ model ก็พอไถไปได้

ดังนั้นเกณท์ถัดมาที่นำมาใช้ก็คือ
"controller ควรมี code ให้น้อยที่สุด"
อันนี้เป็นความชอบส่วนตัวนะ
คือเขียน unit test มันง่ายกว่า funtional test
ดึง logic ออกมาแล้ว มัน test ง่ายดี

คำถามถัดมาก็คือ ถ้าอยู่นอก controller จะให้อยู่ที่ไหน
1. class method ใน Model
2. $RAIL_ROOT/lib
3. Plugin
4. Gem

อันนี้พิจารณา "ความไกล้" กับ "reuse issue"
ในข้อนี้มันไกล้ model มาก, ไม่มีประเด็น reuse
ดังนั้นจึงตกใน ข้อ 1

apirak's picture

ถ้าพิจารณาจากความใกล้ + ให้ controler มี code น้อยที่สุด
การเปลี่ยน data type ก็น่าจะอยู่ใน model หรือเปล่าครับ

แนวคิด work มาเลยครับ ผมขอเอาไปใช้บ้างนะ

Apirak

อืมม์ จะว่าไปก็ใช่นะ การเปลี่ยน datatype ว่าไป บางอย่างก็ไกล้ model นะ
มันก้ำกึงนะ

อย่างพวก date
date ที่ส่งมาเป็น string
ใครควรจะแปลงดี
เนื่องจากมันมีประเด็น locale หรือ format
ที่ไกล้กับ UI มากกว่า

apirak's picture

คุณ pphetra หมายถึง ถ้าเปลี่ยน datatype เพื่อการแสดงผล ก็เอาไว้ใน view แต่ถ้าเปลี่ยน datatype หรือ split เพื่อเก็บข้อมูลก็เอาไว้ใน model หรอครับ

หรือเราจะนิยามว่าถ้าเงื่อนไขในการตัดสินใจขึ้นอยู่กับ layer ไหนก็ให้เก็บที่นั่น เช่น date ต้องอาศัย local ก็เลยต้องเอาไว้ใน view ส่วนการ split string ต้องรู้คุณลักษณะของฐานข้อมูล (เผื่อเปลี่ยนแปลงในอนาคต) เลยต้องเอาไว้ใน model... แบบนี้หรือเปล่าครับ

Apirak

pattern นี้ก็น่าสนใจนะ
Another Rails Presenter Example

ย้าย Codenone

ประกาศย้าย Codenone ไปใช้ Forum ของ Blognone แทนครับ ตามไปตั้งกระทู้ต่อได้ที่ Codenone Forum (รายละเอียดอ่านจากกระทู้ ย้าย Codenone ไปรวมกับ Blognone)

กระทู้เก่าๆ จะย้ายตามไปในภายหลัง ตอนนี้ปิดการโพสต์กระทู้ไว้ เหลือไว้เฉพาะอ้างอิงเท่านั้น