edge
เพิ่มเติมที่ rubyonrails.org: เพิ่มเติมเกี่ยวกับ Ruby on Rails

คู่มือเอพีไอ

คู่มือนี้เอกสารแนะนำการเขียนเอพีไอของ Ruby on Rails

หลังจากอ่านคู่มือนี้คุณจะรู้:

1 RDoc

เอกสารเอพีไอของ Rails ถูกสร้างขึ้นด้วย RDoc ในการสร้างเอกสาร ในการสร้างเอกสาร ตรวจสอบให้แน่ใจว่าคุณอยู่ในไดเรกทอรีของเรลส์ รัน bundle install และรันคำสั่ง:

$ bundle exec rake rdoc

ไฟล์ HTML ที่ได้จะอยู่ในไดเรกทอรี ./doc/rdoc

หมายเหตุ: กรุณาอ่านคู่มือ RDoc Markup Reference เพื่อให้ได้ความช่วยเหลือในการใช้ไวยากรณ์

2 ลิงก์

เอกสารเอพีไอของ Rails ไม่ได้ถูกออกแบบมาเพื่อดูบน GitHub ดังนั้นลิงก์ควรใช้รูปแบบ link ของ RDoc ที่สัมพันธ์กับเอพีไอปัจจุบัน

สาเหตุที่เป็นเช่นนั้นเนื่องจากความแตกต่างระหว่าง GitHub Markdown และ RDoc ที่ถูกสร้างขึ้นที่ api.rubyonrails.org และ edgeapi.rubyonrails.org

ตัวอย่างเช่น เราใช้ [link:classes/ActiveRecord/Base.html] เพื่อสร้างลิงก์ไปยังคลาส ActiveRecord::Base ที่ถูกสร้างขึ้นโดย RDoc

นี่เป็นวิธีที่แนะนำกว่าการใช้ URL สมบูรณ์ เช่น [https://api.rubyonrails.org/classes/ActiveRecord/Base.html] ซึ่งจะพาผู้อ่านออกนอกเวอร์ชันเอกสารปัจจุบัน (เช่น edgeapi.rubyonrails.org)

3 คำพูด

เขียนประโยคที่เรียบง่ายและกระชับ ความกระชับเป็นจุดเด่น: ไปตรงไปจุด

เขียนในรูปปัจจุบัน: "คืนค่าแฮชที่...", แทนที่จะเป็น "คืนค่าแฮชที่..." หรือ "จะคืนค่าแฮชที่..."

เริ่มความคิดเริ่มต้นด้วยตัวพิมพ์ใหญ่ ปฏิบัติตามกฎการใช้เครื่องหมายวรรคตอนปกติ:

# ประกาศ attribute reader ที่มีการสนับสนุนจากตัวแปรอินสแตนซ์ที่มีชื่อภายใน
def attr_internal_reader(*attrs)
  # ...
end

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

เอกสารควรกระชับแต่ครอบคลุมทุกกรณี สำรวจและเอกสารกรณีพิเศษ สิ่งที่เกิดขึ้นถ้าโมดูลไม่มีชื่อ? สิ่งที่เกิดขึ้นถ้าคอลเลกชันว่างเปล่า? สิ่งที่เกิดขึ้นถ้าอาร์กิวเมนต์เป็นค่าว่าง?

ชื่อที่เหมาะสมของส่วนประกอบของ Rails มีช่องว่างระหว่างคำ เช่น "Active Support" ActiveRecord เป็นโมดูลของ Ruby ในขณะที่ Active Record เป็น ORM ควรใช้ชื่อส่วนประกอบของ Rails อย่างสม่ำเสมอในเอกสาร

เมื่ออ้างถึง "แอปพลิเคชัน Rails" ในขณะที่ไม่ได้พูดถึง "เอ็นจิน" หรือ "ปลั๊กอิน" ให้ใช้ "แอปพลิเคชัน" เอกสาร Rails ไม่ใช่ "บริการ" ยกเว้นการอภิปรายเฉพาะเรื่องเกี่ยวกับสถาปัตยกรรมที่เชื่อมโยงกับบริการ

สะกดชื่อถูกต้อง: Arel, minitest, RSpec, HTML, MySQL, JavaScript, ERB, Hotwire หากไม่แน่ใจ โปรดดูที่แหล่งที่มีอำนาจเช่นเอกสารอย่างเป็นทางการของพวกเขา

ใช้คำว่า "an" สำหรับ "SQL" เช่น "an SQL statement" และ "an SQLite database"

เลือกใช้คำที่ไม่มี "you" และ "your" ตัวอย่างเช่น แทนที่จะเป็น

If you need to use `return` statements in your callbacks, it is recommended that you explicitly define them as methods.

ให้ใช้รูปแบบนี้:

If `return` is needed, it is recommended to explicitly define a method.

อย่างไรก็ตาม เมื่อใช้สรรพนามเพื่ออ้างถึงบุคคลที่เป็นสมมติ เช่น "ผู้ใช้ที่มีคุกกี้เซสชัน" ควรใช้สรรพนามที่เป็นเพศเดียวกัน (พวกเขา/ของพวกเขา/พวกเขา) แทนที่จะใช้:

  • เขา...ใช้พวกเขา
  • เขา...ใช้พวกเขา
  • เขา...ใช้พวกเขา
  • เขา...ใช้พวกเขา
  • เขาเอง...ใช้พวกเขาเอง

กรุณาใช้ภาษาอังกฤษแบบอเมริกัน (color, center, modularize, เป็นต้น) ดูรายการของความแตกต่างในการสะกดคำภาษาอังกฤษระหว่างอเมริกันและบริติชที่นี่

4 Oxford Comma

กรุณาใช้ Oxford comma ("red, white, and blue" แทนที่จะใช้ "red, white and blue").

5 ตัวอย่างโค้ด

เลือกตัวอย่างที่มีความหมายและครอบคลุมเนื้อหาพื้นฐานและจุดที่น่าสนใจหรือข้อผิดพลาด

ใช้ช่องว่างสองช่องเพื่อเยื้องโค้ด - กล่าวคือสำหรับวัตถุประสงค์ในการทำเครื่องหมาย, ใช้ช่องว่างสองช่องเมื่อเทียบกับขอบเขตซ้าย ตัวอย่างเองควรใช้ รูปแบบการเขียนโค้ด Rails

เอกสารที่สั้นไม่จำเป็นต้องมีป้ายกำกับ "ตัวอย่าง" ที่ชี้นำไปยังโค้ดตัวอย่าง; โค้ดตัวอย่างจะตามหลังย่อหน้า:

# แปลงคอลเลกชันขององค์ประกอบให้เป็นสตริงที่จัดรูปแบบโดยเรียกใช้ +to_s+ บนองค์ประกอบทั้งหมดและรวมกัน
#
#   Blog.all.to_fs # => "First PostSecond PostThird Post"

ในทางกลับกัน, ส่วนโค้ดเอกสารที่มีโครงสร้างใหญ่อาจมีส่วน "ตัวอย่าง" แยกต่างหาก:

# ==== ตัวอย่าง
#
#   Person.exists?(5)
#   Person.exists?('5')
#   Person.exists?(name: "David")
#   Person.exists?(['name LIKE ?', "%#{query}%"])

ผลลัพธ์ของนิพจน์จะตามหลังและถูกนำเสนอโดย "# => " จัดตำแหน่งให้ตรงกันแนวตั้ง:

# สำหรับการตรวจสอบว่าจำนวนเต็มเป็นคู่หรือคี่
#
#   1.even? # => false
#   1.odd?  # => true
#   2.even? # => true
#   2.odd?  # => false

หากบรรทัดยาวเกินไป ความคิดเห็นอาจถูกวางบนบรรทัดถัดไป:

#   label(:article, :title)
#   # => <label for="article_title">Title</label>
#
#   label(:article, :title, "A short title")
#   # => <label for="article_title">A short title</label>
#
#   label(:article, :title, "A short title", class: "title_label")
#   # => <label for="article_title" class="title_label">A short title</label>

หลีกเลี่ยงการใช้เมธอดการพิมพ์เช่น puts หรือ p สำหรับวัตถุประสงค์ดังกล่าว

ในทางกลับกัน, ความคิดเห็นปกติไม่ใช้ลูกศร:

#   polymorphic_url(record)  # เหมือนกับ comment_url(record)

5.1 SQL

เมื่อเขียนเอกสารสำหรับคำสั่ง SQL ผลลัพธ์ไม่ควรมี => ก่อนผลลัพธ์

ตัวอย่างเช่น

#   User.where(name: 'Oscar').to_sql
#   # SELECT "users".* FROM "users"  WHERE "users"."name" = 'Oscar'

5.2 IRB

เมื่อเขียนเอกสารสำหรับพฤติกรรมของ IRB (Ruby's interactive REPL) ให้เติมคำสั่งด้วย irb> และผลลัพธ์ควรเติมด้วย =>

ตัวอย่างเช่น

# ค้นหาลูกค้าด้วย primary key (id) 10
#   irb> customer = Customer.find(10)
#   # => #<Customer id: 10, first_name: "Ryan">

5.3 Bash / Command-line

สำหรับตัวอย่างคำสั่งบรรทัดคำสั่งให้เติม $ ไว้ข้างหน้าคำสั่ง ผลลัพธ์ไม่ต้องเติมอะไรข้างหน้า

# รันคำสั่งต่อไปนี้:
#   $ bin/rails new zomg
#   ...

6 บูลีน

ในประพจน์และฟล็อกควรใช้ความหมายของบูลีนในการเอกสารเนื่องจากค่าที่แน่นอน

เมื่อใช้ "true" หรือ "false" ตามที่กำหนดใน Ruby ให้ใช้ตัวอักษรธรรมดา สำหรับ singletons true และ false ให้ใช้ตัวอักษรคงความกว้าง กรุณาหลีกเลี่ยงคำเช่น "truthy" Ruby กำหนดว่าอะไรเป็นจริงและเท็จในภาษา ดังนั้นคำเหล่านี้มีความหมายทางเทคนิคและไม่ต้องมีคำทดแทน ตามกฎข้อหนึ่ง ไม่ควรเอกสารสิ่งที่เป็น Singleton น้อยที่สุด นั่นป้องกันการสร้างสรรค์เทียมเช่น !! หรือ ternaries อนุญาตให้ทำการเปลี่ยนแปลงโครงสร้างใหม่และโค้ดไม่จำเป็นต้องพึ่งพาค่าที่แน่นอนที่ส่งกลับจากเมธอดที่เรียกใช้ในการดำเนินการ

ตัวอย่าง:

`config.action_mailer.perform_deliveries` ระบุว่าจะส่งอีเมลจริงหรือไม่และมีค่าเป็น true ตามค่าเริ่มต้น

ผู้ใช้ไม่จำเป็นต้องทราบค่าเริ่มต้นจริงของตัวแปรนั้น ดังนั้นเราเพียงแค่เอกสารความหมายของตัวแปรเป็น boolean เท่านั้น

ตัวอย่างที่มีเงื่อนไข:

# คืนค่า true ถ้าคอลเลกชันว่างเปล่า
#
# ถ้าคอลเลกชันถูกโหลดแล้ว
# มันเทียบเท่ากับ <tt>collection.size.zero?</tt> ถ้า
# คอลเลกชันยังไม่ถูกโหลด มันเทียบเท่ากับ
# <tt>!collection.exists?</tt> ถ้า
# คอลเลกชันยังไม่ถูกโหลดและคุณกำลังจะดึงระเบียนอยู่อย่างไรก็ตาม คุณควร
# เช็ค <tt>collection.length.zero?</tt> ดีกว่า
def empty?
  if loaded?
    size.zero?
  else
    @target.blank? && !scope.exists?
  end
end

API ระวังไม่ให้ผูกมัดกับค่าใด ๆ ที่เฉพาะเจาะจง มีเฉพาะความหมายของเมธอดเท่านั้น นั่นเพียงพอ

7 ชื่อไฟล์

ตามกฎข้อหนึ่ง ใช้ชื่อไฟล์เป็นสัมพันธ์กับรากแอปพลิเคชัน:

config/routes.rb            # ใช่
routes.rb                   # ไม่ใช่
RAILS_ROOT/config/routes.rb # ไม่ใช่

8 แบบอักษร

8.1 แบบอักษรคงที่

ใช้แบบอักษรคงที่สำหรับ:

  • ค่าคงที่ โดยเฉพาะชื่อคลาสและโมดูล
  • ชื่อเมธอด
  • ค่าคงที่เช่น nil, false, true, self
  • สัญลักษณ์
  • พารามิเตอร์ของเมธอด
  • ชื่อไฟล์
class Array
  # เรียกใช้ +to_param+ บนสมาชิกทั้งหมดและรวมผลลัพธ์ด้วยเส้นหนึ่ง นี่ใช้กับ +url_for+ ใน Action Pack
  def to_param
    collect { |e| e.to_param }.join '/'
  end
end

คำเตือน: การใช้ +...+ สำหรับแบบอักษรคงที่ทำงานเฉพาะกับเนื้อหาที่เรียบง่ายเช่นคลาสธรรมดาๆ โมดูล ชื่อเมธอด สัญลักษณ์ เส้นทาง (พร้อมเส้นทางสูงสุด) เป็นต้น กรุณาใช้ <tt>...</tt> สำหรับสิ่งอื่น ๆ

คุณสามารถทดสอบผลลัพธ์ RDoc ได้อย่างรวดเร็วด้วยคำสั่งต่อไปนี้:

$ echo "+:to_param+" | rdoc --pipe
# => <p><code>:to_param</code></p>

ตัวอย่างเช่น โค้ดที่มีช่องว่างหรือเครื่องหมายคำพูดควรใช้รูปแบบ <tt>...</tt>

8.2 แบบอักษรปกติ

เมื่อ "true" และ "false" เป็นคำศัพท์ภาษาอังกฤษไม่ใช่คำสำคัญของ Ruby ให้ใช้แบบอักษรปกติ:

# รันการตรวจสอบความถูกต้องภายในบริบทที่ระบุ
# คืนค่า true ถ้าไม่พบข้อผิดพลาด มิฉะนั้นคืนค่า false
#
# ถ้าอาร์กิวเมนต์เป็น false (ค่าเริ่มต้นคือ +nil+) บริบทจะถูกตั้งค่าเป็น <tt>:create</tt> ถ้า <tt>new_record?</tt> เป็นจริง
# และถูกตั้งค่าเป็น <tt>:update</tt> ถ้าไม่ใช่
#
# การตรวจสอบความถูกต้องที่ไม่มีตัวเลือก <tt>:on</tt> จะทำงานไม่ว่าบริบทจะเป็นอย่างไร
# การตรวจสอบความถูกต้องที่มีตัวเลือก <tt>:on</tt> จะทำงานเฉพาะในบริบทที่ระบุ
def valid?(context = nil)
  # ...
end

9 รายการคำอธิบาย

ในรายการตัวเลือก พารามิเตอร์ เป็นต้น ใช้เครื่องหมายขีดกลางระหว่างรายการและคำอธิบาย (อ่านง่ายกว่าเครื่องหมายคอลอนเพราะตามปกติตัวเลือกจะเป็นสัญลักษณ์):

# * <tt>:allow_nil</tt> - ข้ามการตรวจสอบความถูกต้องหากแอตทริบิวต์เป็น +nil+

คำอธิบายเริ่มต้นด้วยตัวพิมพ์ใหญ่และจบด้วยจุดสิ้นสุด - เป็นภาษาอังกฤษมาตรฐาน

วิธีที่สองเมื่อคุณต้องการให้ข้อมูลเพิ่มเติมและตัวอย่างคือการใช้รูปแบบส่วนตัวเมื่อต้องการให้ข้อมูลเพิ่มเติมและตัวอย่าง ActiveSupport::MessageEncryptor#encrypt_and_sign เป็นตัวอย่างที่ดีในเรื่องนี้

# ==== ตัวเลือก
#
# [+:expires_at+]
#   วันที่และเวลาที่ข้อความหมดอายุ หลังจากวันที่และเวลานี้
#   การตรวจสอบข้อความจะล้มเหลว
#
#     message = encryptor.encrypt_and_sign("hello", expires_at: Time.now.tomorrow)
#     encryptor.decrypt_and_verify(message) # => "hello"
#     # ผ่านไป 24 ชั่วโมง...
#     encryptor.decrypt_and_verify(message) # => nil

เมธอดที่สร้างขึ้นโดยใช้ (module|class)_eval(STRING) จะมีคอมเมนต์ข้างข้างโค้ดที่สร้างขึ้น คอมเมนต์นั้นจะอยู่ห่างจากเทมเพลต 2 ช่องว่าง:

(module|class)_eval(STRING) code comments

หากบรรทัดที่ได้มีความกว้างมากเกินไป เช่น 200 คอลัมน์หรือมากกว่า ให้วางคอมเมนต์ด้านบนของเรียกใช้:

# def self.find_by_login_and_activated(*args)
#   options = args.extract_options!
#   ...
# end
self.class_eval %{
  def self.#{method_id}(*args)
    options = args.extract_options!
    ...
  end
}, __FILE__, __LINE__

10 การกำหนดการมองเห็นของเมธอด

เมื่อเขียนเอกสารสำหรับ Rails นั้น สิ่งสำคัญคือการเข้าใจความแตกต่างระหว่าง public user-facing API กับ internal API

Rails เช่นเดียวกับหลายๆ ไลบรารีอื่นๆ ใช้คำสำหรับการกำหนด internal API จาก Ruby แต่ public API นั้นมีแนวคิดที่ต่างกันเล็กน้อย แทนที่จะสมมติว่าเมธอด public ทั้งหมดถูกออกแบบสำหรับการใช้งานโดยผู้ใช้ Rails ใช้คำสั่ง :nodoc: เพื่อทำเครื่องหมายเมธอดเหล่านี้ว่าเป็น internal API

นั่นหมายความว่ามีเมธอดใน Rails ที่มีการมองเห็นเป็น public ที่ไม่ได้เป็นไปตามเอกสารสำหรับผู้ใช้

ตัวอย่างเช่น ActiveRecord::Core::ClassMethods#arel_table:

module ActiveRecord::Core::ClassMethods
  def arel_table # :nodoc:
    # ทำบางอย่างเวทนา..
  end
end

หากคุณคิดว่า "เมธอดนี้ดูเหมือนเมธอดคลาส public สำหรับ ActiveRecord::Core" คุณก็ถูกต้อง แต่แท้จริงทีม Rails ไม่ต้องการให้ผู้ใช้พึ่งพาเมธอดนี้ ดังนั้นพวกเขาทำเครื่องหมายว่า :nodoc: และมันจะถูกลบออกจากเอกสารสาธารณะ แนวคิดที่อยู่หลังการกระทำนี้คือเพื่อให้ทีมสามารถเปลี่ยนแปลงเมธอดเหล่านี้ตามความต้องการภายในของพวกเขาในแต่ละรุ่นได้ตามที่พวกเขาต้องการ ชื่อของเมธอดนี้อาจเปลี่ยน หรือค่าที่ส่งกลับ หรือคลาสทั้งหมดอาจหายไป ไม่มีการรับประกันดังนั้นคุณไม่ควรพึ่งพา API นี้ในปลั๊กอินหรือแอปพลิเคชันของคุณ มิฉะนั้นคุณอาจเสี่ยงที่จะทำให้แอปหรือเจมของคุณเสียหายเมื่อคุณอัปเกรดไปยังรุ่น Rails ที่ใหม่กว่า

เป็นสิ่งสำคัญที่ควรพิจารณาว่า API นี้เหมาะสำหรับการใช้งานโดยผู้ใช้หรือไม่ ทีม Rails มุ่งมั่นที่จะไม่ทำการเปลี่ยนแปลงที่ทำให้เกิดความไม่สามารถใช้งานได้กับ API สาธารณะในแต่ละรุ่นโดยไม่ผ่านกระบวนการเกณฑ์การเลิกใช้งานเต็มรูปแบบ แนะนำให้คุณใช้ :nodoc: กับเมธอด/คลาสภายในของคุณทั้งหมด ยกเว้นว่ามันเป็น private อยู่แล้ว (หมายความว่ามองเห็น) ในกรณีนั้นมันจะเป็น internal โดยค่าเริ่มต้น เมื่อ API คงที่แล้วความเห็นสามารถเปลี่ยนแปลงได้ แต่การเปลี่ยนแปลง public API ยากกว่าเนื่องจากความเข้ากันได้ย้อนกลับ

คลาสหรือโมดูลถูกทำเครื่องหมายด้วย :nodoc: เพื่อแสดงว่าเมธอดทั้งหมดเป็น internal API และไม่ควรใช้โดยตรง

สรุปว่าทีม Rails ใช้ :nodoc: เพื่อทำเครื่องหมายเมธอดและคลาสที่มองเห็นได้สำหรับการใช้งานภายใน การเปลี่ยนแปลงในการมองเห็นของ API ควรถูกพิจารณาอย่างรอบคอบและถูกพูดคุยผ่าน pull request ก่อน

11 เกี่ยวกับ Rails Stack

เมื่อเขียนเอกสารส่วนของ Rails API นั้น สิ่งสำคัญคือจำไว้ว่ามีส่วนประกอบทั้งหมดที่เกี่ยวข้องกับ Rails stack นี้หมายความว่าพฤติกรรมอาจเปลี่ยนแปลงขึ้นอยู่กับขอบเขตหรือบริบทของเมธอดหรือคลาสที่คุณพยายามเอกสาร

ในสถานที่ต่าง ๆ มีพฤติกรรมที่แตกต่างกันเมื่อคุณพิจารณาสแต็กทั้งหมด ตัวอย่างหนึ่งคือ ActionView::Helpers::AssetTagHelper#image_tag:

# image_tag("icon.png")
#   # => <img src="/assets/icon.png" />

แม้ว่าพฤติกรรมเริ่มต้นสำหรับ #image_tag จะเป็นการส่งคืนเสมอ /images/icon.png เราต้องพิจารณาสแต็ก Rails ทั้งหมด (รวมถึง Asset Pipeline) เราอาจเห็นผลลัพธ์ที่เห็นได้ดังกล่าว

เราสนใจเฉพาะพฤติกรรมที่ประสบการณ์เมื่อใช้สแต็กเริ่มต้นของ Rails ทั้งหมด

ในกรณีนี้ เราต้องการเอกสารพฤติกรรมของ framework ไม่ใช่เฉพาะเมธอดนี้

หากคุณมีคำถามเกี่ยวกับวิธีที่ทีม Rails จัดการ API บางอย่าง อย่าลังเลที่จะเปิดตั๋วหรือส่งแพทช์ไปยัง ติดตามปัญหา

ข้อเสนอแนะ

คุณสามารถช่วยปรับปรุงคุณภาพของคู่มือนี้ได้

กรุณาช่วยเพิ่มเติมหากพบข้อผิดพลาดหรือข้อผิดพลาดทางความจริง เพื่อเริ่มต้นคุณสามารถอ่านส่วน การสนับสนุนเอกสาร ของเราได้

คุณอาจพบเนื้อหาที่ไม่สมบูรณ์หรือเนื้อหาที่ไม่ได้อัปเดต กรุณาเพิ่มเอกสารที่ขาดหายไปสำหรับเนื้อหาหลัก โปรดตรวจสอบ Edge Guides ก่อนเพื่อตรวจสอบ ว่าปัญหาได้รับการแก้ไขหรือไม่ในสาขาหลัก ตรวจสอบ คู่มือแนวทาง Ruby on Rails เพื่อดูรูปแบบและกฎเกณฑ์

หากคุณพบข้อผิดพลาดแต่ไม่สามารถแก้ไขได้เอง กรุณา เปิดปัญหา.

และสุดท้าย การสนทนาใด ๆ เกี่ยวกับ Ruby on Rails เอกสารยินดีต้อนรับที่สุดใน เว็บบอร์ดอย่างเป็นทางการของ Ruby on Rails.