10 mẹo hữu ích cho các lập trình viên Ruby on Rails (RoR)

Rails là một framework web theo mô hình MVC được viết trên ngôn ngữ lập trình Ruby. So với các framework khác thì Rails có lợi thế lớn hơn rất nhiều, nó có giá trị quy ước về cấu hình. Nếu bạn tuân theo các quy ước đúng, bạn có thể tránh được các tập tin có cấu hình dài dòng, chỉ cần những thứ cần cho công việc. Bạn sẽ tiết kiệm thời gian viết những file cấu hình nhàm chán để dành nhiều thời gian tập trung vào logic nghiệp vụ.

Ngày nay, Rails rất được yêu thích và được sử dụng phổ biến khắp mọi nơi trên thế giới. Nhưng đừng nhầm tưởng nó là giải pháp hoàn hảo tuyệt đối cho mọi vấn đề.

Dưới đây sẽ là 10 mẹo hữu ích về ý tưởng và tài nguyên cho người phát triển Ruby on Rails. Nếu có ý tưởng gì hay, bạn hãy comment đề xuất của mình vào bên dưới bài viết nhé (yeah)

1. Các Plug-In giúp tiết kiệm thời gian

Rails có một cấu trúc plug-in được xác định rõ ràng, giúp cho bạn dễ dàng cài đặt và sử dụng trong ứng dụng của mình. David Heinemeier Hansson, cha đẻ của Rails, cho biết anh ấy sử dụng 5-6 plug-in trong mỗi ứng dụng Rails của mình.

Một nguyên tắc vàng dành cho lập trình viên : "the best code is no code at all". Tôi thì không giỏi tiếng Anh cho lắm nên tôi hiểu câu nói này đại loại kiểu như code tốt nhất không phải là code tất cả mọi thứ, hoặc nó cũng có nghĩa nôm na với câu nói "viết một lần, chạy mọi nơi" . Để việc phát triển trong Rails có năng suất cao thì một phần là nhờ vào việc chúng ta không cần phải viết hết tất cả các mã cho một chương trình mà có một người nào đó trong cộng đồng dev đã viết các mã thành 1 plug-in cung cấp một chức năng nào đó mà chúng ta cần. Dưới đây là một vài cách để cài đặt plug-in trong Rails, tuy nhiên đây là cài đặt bằng tay còn đa số là chạy script để cài đặt các plug-in tự động:

# Cài đặt từ 1 git repo : plug-in hỗ trợ tính năng phân trang
script/plugin install git://github.com/mislav/will_paginate.git

# Cài đặt từ 1 url : plug-in cung cấp lịch
script/plugin install http://topfunky.net/svn/plugins/calendar_helper

Bạn có thể tiết kiệm rất nhiều thời gian và rắc rối nếu bạn có kỹ năng tìm kiếm trên Web tốt (đặc biệt là GitHub). Một vài địa chỉ tốt để tìm các plug-in như Core Rails, Railsify và Rails Plug-in Directory. Bạn cần phối hợp với một API có sẵn hoặc tiêu thụ một số loại dữ liệu có định dạng chuẩn, hoặc cần gắn thẻ, phân trang hoặc sử dụng một tính năng phổ biến nào khác của ứng dụng web? Khả năng cao là đã có lập trình viên RoR nào đó viết sẵn các tính năng đó thành các plug-in để bạn sẵn tải về và dùng.

2. Kiểm thử thật thú vị và dễ dàng với Rspec

Khi nói đến từ test, đa số mọi người thường nghĩ đến những kỷ niệm không vui với những bài kiểm tra ở trường. Mặc dù từ test ở đây mang hàm ý khác nhưng đối với cá nhân tôi thì việc test với Rspec cũng có ý nghĩ tương tự, nó để lại trong tôi ấn tượng khó quên đến tận cả sau này.

Khi mới vào công ty và trải qua kỳ trainning 2 tháng cho new dev, tôi được vào làm dự án thật và task đầu tiên được giao tôi đã đụng mặt với Rspec. Tôi có viết 1 hàm khoảng 5-6 dòng trong model sau đó đẩy pull-request như bình thường. Tôi hào hứng vì vượt qua task đầu tiên một cách "ngon lành" nhưng sau đó tôi đã nhận được comment từ team leader là viết Rspec cho hàm này vì mỗi khi bạn thêm 1 hàm hoặc phương thức mới trong model thì bạn đều phải viết Rspec cho nó. Vì trong khi trainning chúng tôi được "miễn" phần Rspec này nên tới khi gặp nó, tôi hoang mang không biết đây là cái quái quỷ gì. Tôi bắt đầu mò lại tutorial lúc trainning đồng thời mò mẫm trên mạng, hì hục mãi cũng viết được cái Rspec nhưng tới khi chạy test thì thất vọng toàn tập, cái tôi nhận được chỉ là màn hình đỏ lòm với rất rất nhiều các thông báo failure. Cố gắng trong vô vọng mãi tôi đành phải nhờ tới sự giúp đỡ của leader. Vì leader của tôi là người Nhật nên chúng tôi đành trao đổi qua ngôn ngữ trung gian là tiếng Anh, có lúc nói với nhau không hiểu thì lại phải ghi ra giấy. Làm tới đâu anh ấy hướng dẫn từng bước cho tôi đến đó, tới khi chạy pass hết tất cả Rspec, tôi sướng rơn trong người, háo hức như bắt được vàng, nhìn lại đồng hồ cũng đã gần 10h đêm, mắt hoa lên vì ngồi máy tính quá lâu.

Kể cho bạn câu chuyện trên đây không phải chỉ là để tám tào lao mà tôi chỉ muốn nhấn mạnh tới tầm quan trọng của Rspec và kỹ năng viết Rspec của dev quan trọng như thế nào. Leader của tôi có thể chọn phương án là viết spec thay tôi hoặc đổi cho tôi task khác, nhưng thay vì đó anh ấy lại kiên nhẫn ngồi lại chỉ dẫn tôi từng bước một, mong muốn của anh ấy là đã là 1 dev thì phải biết viết Rspec thành thạo.

Rspec được hiểu như là một bộ script test tự động. Nó là các chương trình trợ giúp nhỏ được viết ra để chạy những đoạn mã chính để đảm bảo rằng đoạn chương trình đó thực hiện đúng. Khi Rspec đúng, việc testing sẽ cải thiện quy trình làm việc và tăng sự tin tưởng vào các kết quả và đoạn chương trình mà bạn đã viết.

Thay vì sử dụng framwork test có sẵn trong Rails (Rails mặc định sử dụng mini test) thì vài năm trở lại đây Rpsec đã được sử dụng rộng rãi trong cộng đồng RoR, cú pháp Rspec rất rõ ràng và dễ hiểu:

#describe...end : đoạn script test một function nào đó
describe "My Cool library" do
  #before do... : trước khi chạy kịch bản thì làm gì đó, thường dùng để nhóm những thao tác chung như khởi tạo dữ liệu để code dễ đọc và đúng chuẩn hơn
  before do
    @cool = Cool.new
  end

  #should be ... : kết quả mong muốn sau khi chạy các lệnh bên trong
  it "should be full of penguins." do
    @cool.get_penguins!
    @cool.penguin_count.should == 10
  end

  it "should melt if it gets too warm"
end

Khối block chứa bối cảnh và mỗi khẳng định bên trong nó là các case (kịch bản) để giải thích code của bạn nên làm gì. Đây là giai đoạn quan trọng nhất : viết ra các khẳng định dựa vào câu hỏi "Mã này nên làm gì sau đó?"

Rspec cho phép bạn rời khỏi khối đang viết và nhanh chóng suy nghĩ tất cả các chức năng cần có, viết phác thảo các ý chính cho các chức năng này, sau đó mới quay lại và thực hiện các test khi bạn viết code. Trong thời gian chờ, Rspec sẽ xem các test này đang trong trạng thái "pending" và đưa ra cho bạn vài nhắc nhở về chúng trong quá trình chạy test của bạn. Một điều tuyệt vời nữa là khi đã có đủ các test thì chúng sẽ cho bạn thấy tất cả các code của bạn liên quan với nhau như thế nào, giúp bạn dễ dàng biết được những thay đổi gần đây của mình có ảnh hưởng thế nào tới cả chương trình (phá vỡ cái gì đó chẳng hạn). Rspec còn giúp dễ dàng tạo những vùng phủ sóng thử nghiệm tốt nhờ việc sử dụng các bộ tạo tùy chỉnh để tạo các test phù hợp với phần còn lại của code:

$ script/generate rpsec_scaffold MyModel

Khi đã kiểm tra để đảm bảo rằng các chức năng cơ bản đã hoạt động thành công, bạn có thể yên tâm thay đổi và thêm mã code mới mà không cần lo lắng về những bug không nhìn thấy được. Miễn là bạn chạy test thường xuyên, bạn sẽ biết ngay khi bạn phá vỡ (phá hỏng) một cái gì đó 😃

3. Muốn tiết kiệm thời gian - Hãy sử dụng Rake

Ngoài những mã ứng dụng cụ thể, trong một project còn có các yêu cầu như : tạo dữ liệu mẫu, truy vấn các dịch vụ web, chuyển các tập tin (file), viết lại các đoạn mã ngắn, v.v... Hãy sử dụng Rake thay vì việc cố nhồi nhét 1 kịch bản nào đó vào trong 1 migration hoặc controller để thực hiện những điều trên.

Rake là một công cụ hỗ trợ chạy các ruby code bên trong các Makefile. Rake cho phép bạn định nghĩa list các task kèm theo dependency của nó, với mục đích gom nhóm các đoạn code Ruby thường xuyên được thực hiện vào một task chung và sử dụng lại chúng nhiều lần. Có 1 vài Rake task đã được định nghĩa sẵn trong Rails, để xem các task này bạn hãy chạy lệnh $ rake -T

macbook$ rake -T

rake data:bootstrap # tải một số dữ liệu cơ bản [cảnh báo : nó sẽ xóa sạch thư mục và thay thế bằng thư mục khác rake db:create:all # Tạo tất cả cơ sở dữ liệu cục bộ được định nghĩa trong file config/database.yml rake db:drop # Xóa tất cả cơ sở dữ liệu trong RAILS_EVN hiện thời ... rake ts:run # Dừng nếu đang chạy, sau đó khởi động Sphinx searchd daemon đang sử dụng các cài đặt của Thinking Sphinx rake ts:start # Khởi động Sphinx searchd daemon đang sử dụng các cài đặt của Thinking Sphinx rake ts:stop # Dừng Sphinx searchd daemon đang sử dụng các cài đặt của Thinking Sphinx

Việc thêm các tác vụ Rake cũng khá dễ dàng. Ở ví dụ dưới đây, bạn sẽ thấy rằng task được namespace và có một mô tả và tên cho nó, cho phép bạn viết trong Ruby:

namespace :data do
  desc "load in some basic data [caution: will nuke and replcace categories, categorizations and inventory items]"
  task :bootstrap => :environment do
    # xóa các bản ghi đang tồn tại của các model : Category, Categorization, InventoryItem
    [Category, Categorization, InventoryItem].each{|m| m.find(:all).each{|i| i.destroy}}
    #tạo item mới cho InventoryItem
    InventoryItem.create! :name => "Compass"
    ##tạo item mới cho InventoryItem và gán bằng c
    c = Category.create! :name => "Basic Apparel"

    ["Men’s Heavyweight Cotton T",
    "Men’s Heavyweight Polo",
    "Women’s Organic Cotton Fitted T",
    "Women’s Fitted Polo",
    "Children’s T-Shirt",
    "Jr’s Distressed Hoodie",
    "Hemp Messenger Bag"].each do |name|
      #InventoryItem là lớp kế thừa từ Category. Từ Category tên c, tạo mới các InventoryItem là con của nó với tên lần lượt là các phần tử trong mảng ở vòng lặp trên
      c.inventory_items.create! :name => name
    end

   ...

end

4. Theo dõi các trường hợp ngoại lệ

Các trường hợp ngoại lệ có thể xảy ra bất cứ lúc nào, và khi đó bạn muốn biết về điều đó. Khách hàng của bạn sẽ không phải là người báo với bạn khi có một vấn đề nào đó xảy ra; bạn cần phải luôn trong trạng thái sẵn sàng để biết về vấn đề và làm việc để giải quyết nó. Thông báo ngoại lệ đã có sẵn trong Rails. Các plug-ins về thông báo ngoại lệ làm việc thông báo trở nên dễ dàng hơn. Ngoài ra, một số dịch vụ như Airbrake Bug Tracker và Get Exceptional cũng thêm nhiều giá trị cho ứng dụng của bạn. Cả 2 dịch vụ này đều dễ dàng cài đặt và nó cung cấp giao diện tuyệt vời cho việc theo dõi ngoại lệ của bạn. Bạn có thể đăng ký tài khoản free để thử.

Bằng việc tập trung các ngoại lệ (centralizing the application exceptions), bạn có thể biết được các trường hợp ngoại lệ xảy ra thường xuyên như thế nào, chúng xảy ra trong môi trường nào (một trình duyệt cụ thể? một vị trí cụ thể?), những tham số nào đã hiện diện và dấu hiệu đầy ngăn xếp (stack). Sự tập trung dữ liệu này giúp bạn xem được các pattern và giải quyết vấn đề nhanh hơn, kết quả làm cho ứng dụng tốt hơn và người dùng hạnh phúc, hài lòng hơn.

5. Trộn và kết hợp giữa các framework và các máy chủ với Rails trên Rack Link

Ở phiên bản 2.3, Rails chạy trên Rack. Rack làm cho nó có thể trộn và kết hợp giữa các framework và các server Ruby Web với nhau. Nếu bạn đang sử dụng framework hỗ trợ nó (ví dụ như Rails, Sinatra, Camping ...) bạn có thể chọn bất kỳ server nào để kết hợp (Mongrel, Thin, Phusion Passenger, ...) và ngược lại.

Ngoài việc giới thiệu tất cả các loại option mới để triển khai, sự thay đổi này còn có ý nghĩa là Rails giờ đây có quyền truy cập vào thế giới thú vị của Rack middleware (trung gian). Bởi vì Rack sống ở giao lộ (giáp ranh) giữa app và server của bạn, nó có thể cung cấp trực tiếp tất cả các chức năng thông thường, một ví dụ tuyệt vời của việc này là Rack::Cache.

Rack::Cache cung cấp một caching layer (lớp bộ nhớ đệm) cho ứng dụng của bạn giúp bạn kiểm soát đơn giản bằng cách gửi các tiêu đề đúng trong các phản hồi của bạn. Nói cách khác, tất cả những gì bạn phải làm là cài đặt một chút mã trong file cấu hình Rack:

require 'rack/cache'

use Rack::Cache,
  :metastore => 'file:/tmp/rack_meta_dir',
  :entitystore => 'file:/tmp/rack_body_dir',
  :verbose => true

Và đảm bảo rằng các controller action gửi đúng header (ví dụ, bằng việc setting request.headers["Cache-Control"]) và Bùm!, bạn đã có bộ nhớ đệm.

6. Dump dữ liệu dễ dàng

Bạn sẽ thường xuyên cần lấy dữ liệu từ môi trường production về môi trường dev (môi trường phát triển) hoặc từ môi trường dev về local của bạn, hoặc từ local của bạn đến local của các lập trình viên khác. Một plug-in được sử dụng là Yaml_db. Plug-in nhỏ bé tiện lợi này cho phép bạn dump hoặc load dữ liệu bằng cách phát hành một lệnh Rack. Dữ liệu này tồn tại trong một file yaml có tên là db/data.yml. Rất tiện lợi và dễ dàng cho việc đọc nếu bạn cần kiểm tra dữ liệu.

7. Giữ các hằng số ở chung một nơi

Ứng dụng nào cũng có các hằng số, chúng là những biến được định nghĩa với dữ liệu không thay đổi, chẳng hạn như là tên của ứng dụng, khẩu hiệu, giá trị cho các tùy chọn quan trọng ... Chúng ta sử dụng tính năng khởi tạo của Rails (Rails initializer) để định nghĩa ra file config/initializers/site_config.rb làm "nhà ở" cho các hằng số này. Bằng việc quy ước này, tất cả các dev trong dự án đều biết chính xác nơi để tìm các hằng số và nhanh chóng thay đổi gì đó.

Nhiều người thắc mắc rằng khi nào nên đặt 1 hằng số vào trong file site_config.rb thay vì lưu chúng trong class mà chúng được dùng tới? Đối với các hằng số chỉ được sử dụng trong một class duy nhất nào đó, thì chúng ta được khuyến nghị nên để nó trong class dùng tới nó. Khi một hằng số được sử dụng nhiều hơn ở vị trí (location) thì nên đặt nó bên trong file site_config.rb. Để tìm hiểu kỹ hơn bạn có thể tham khảo tại trang Rubylearning.

# File config/initializers/site_config.rb

#REPORT_RECIPIENT và REPORT_ADMIN là tên các hằng số, tên hằng số nên viết in hoa
REPORT_RECIPIENT = '[email protected]'
REPORT_ADMIN = '[email protected]'

8. Nên dùng Console khi làm việc với code

Đôi khi sẽ có những dòng code làm bạn tò mò về chúng. Chúng sẽ hoạt động theo cách nào? Kết quả đầu ra là gì? Tôi có thể thay đổi cái gì? ... Đáp ứng điều đó, Rails cung cấp cho chúng ta một tool tuyệt vời được gọi là console. Bằng việc chạy kịch bản/console (gõ lệnh rails c hoặc rails console), bạn sẽ vào được một môi trường tương tác nơi mà bạn có thể truy cập vào code của bạn giống như thể ứng dụng đang được chạy.

Môi trường này rất hữu ích. Nó thường được sử dụng trong môi trường production để nhanh chóng xem dữ liệu mà không cần phải đăng nhập vào cơ sở dữ liệu. Để làm được điều này trong môi trường production, sử dụng script/console RAILS_ENV=production hoặc có thể thay production bằng tên khác trong môi trường khác tương ứng:

macbook$ ./script/console Loading development environment (Rails 2.1.1)

a = Album.find(:first) => #

9. View xấu xí khiến bạn thất vọng? Hãy thử Haml

View (các khung nhìn, thường được hiểu là giao diện) là những trang HTML được Rails tạo ra cho ứng dụng của bạn, đây là những thứ bạn thường xuyên nhìn thấy và sử dụng. Theo mặc định, Rails sử dụng hệ thống template ERb để cho phép bạn nhúng các bit của Ruby vào đánh dấu (markup) của bạn để bạn có thể chèn dữ liệu vào khi cần thiết. Nhưng với HTML bạn sẽ tự hỏi tại sao nó lại quá dài dòng như vậy? Tại sao không ai đó đơn giản hóa nó? Vậy nên Haml ra đời là để tối ưu hóa HTLM. Về cốt lõi, Haml là ngôn ngữ markup thu gọn giúp việc viết HTML dễ dàng hơn có thể sử dụng cho nhiều ngôn ngữ PHP, ASP, ERB...và được sử dụng nhiều nhất là Ruby on Rails.

Haml được quảng cáo như là “markup Haiku.” Cú pháp của nó được lấy cảm hứng từ CSS cho phép bạn tập trung vào ngữ nghĩa của dữ liệu thay vì lo lắng về việc đóng tất cả các thẻ khi sử dụng ERb và HTML. Để tiện so sánh, dưới đây là ví dụ nhỏ về 2 cách viết:

markup trong ERb chuẩn:

<%= print_date %>
<%= current_user.address %>

<%= current_user.email %>
<%= h current_user.bio %>

Haml:

#profile
  .left.column
    #date= print_date
    #address= current_user.address
  .right_column
    #email= current_user.email
    #bio= h(current_user.bio)

10. Biết cần xem những thứ đang xảy ra trong cộng đồng Rails ở đâu

Cả Rails và Ruby đều có những cộng đồng lớn và tích cực, ở đó liên tục tạo ra những thay đổi, những cải tiến và những dự án mới. Cố gắng theo kịp mọi hoạt động này có thể sẽ là khó khăn, nhưng là rất cần thiết nếu bạn muốn có được lợi ích từ công việc tốt nhất của cộng đồng này và không ngừng tăng vốn kiến thức về Rails và Ruby của bạn.

Dưới đây là một số nguồn tổng hợp những hoạt động quan trọng nhất:

Ngoài ra còn có các trang phục vụ cho mục đích trainning Rails:

và một số tờ báo tập hợp tin tức:

Một số diễn đàn khác như danh sách các Rails Core mailing trong Gmail và kênh #rails-core IRC.

Lời kết

Trên đây chỉ là một số tip mình tham khảo được và tâm đắc nên muốn chia sẻ với các bạn. Nếu bạn nào có tip gì hay thì hãy comment phía dưới để cùng thảo luận, học tập nhé (yeah)

Nếu bạn muốn tìm hiểu nguyên gốc rõ hơn có thể tham khảo tại đây: https://www.smashingmagazine.com/2009/02/ruby-on-rails-tips/