Bắt đầu với Ruby on Rails

Mặc dù được tiếp xúc với ngôn ngữ lập trình ruby, đặc biệt là Ruby on Rails chưa lâu nhưng hôm nay mình quyết định viết về một chút hiểu biết cơ bản của mình về Ruby on Rails

Khi mới nhìn vào, có vẻ mọi nguời sẽ thấy Ruby on Rails (Rails) là một ngôn ngữ lập trình khá gọn gàng và dễ dàng để hiểu hết mọi vấn đề. Nhưng khi đi sâu vào hơn một chút, các bạn sẽ thấy đó là cả một thách thức lớn. Và sau một thời gian được tiếp xúc thì dưới đây là phần tìm hiểu của tôi về Rails.

Và như thường lệ, bắt đầu với các định nghĩa cơ bản nào

1. Khái niệm cơ bản trong Rails

  • Ruby là một ngôn ngữ lập trình, tương tự như PHP. Nó có các kiểu biến động (nghĩa là không cần khai báo kiểu “int i”), thông dịch và có thể chỉnh sửa trong khi chạy (ví dụ như thêm các method vào các class). Nó có rất nhiều shortcut giúp cho code bạn nhìn rất rõ ràng. Ngoài ra việc phân ra các method và class cùng giúp cho bạn nhìn rất dễ hiểu.
  • Mọi người thường nhầm lẫn Ruby và Rails là một, kỳ thực không phải vậy. Rails là một gem, hay gọi là một thư viện của Ruby giúp tạo một ứng dụng web, cung cấp các lớp cho việc lưu trữ cơ sở dữ liệu, xử lý các URL và hiển thị HTML (cùng với một webserver, các maintenance task, dòng lệnh sửa lỗi và nhiều thứ nữa).
  • IRB (cái này nếu các bạn đã đọc qua quyển ruby programming chắc sẽ biết) là dòng lệnh tương tác Ruby (Gõ “irb” để sử dụng). Rails có dòng lệnh IRB đặc biệt có thể truy cập vào ứng dụng web trong khi nó đang chạy (tuyệt vời cho việc debug).
  • Rake là Make của Ruby. Định nghĩa và chạy những tác vụ như thiết đặt cơ sở dữ liệu, tải lại dữ liệu, sao lưu thậm chí deploy ứng dụng lên website.
  • Erb, hay Embedded Ruby. Giống như PHP, cho phép đồng thời viết code Ruby ở trong HTML.

Rồi, sau khi cài đặt Ruby và Rails thì giờ các bạn có thể thêm các Rails gem (Mặc du Rails được coi là một gem của Ruby nhưng nó cũng có những gem hỗ trợ khác của riêng mình).

2. Giờ hiểu sâu hơn một chút về Ruby

Thật là khó khăn để học mới một ngôn ngữ hay một thư viện cùng một lúc. Đây là một số chú ý dành cho những ai đã có kiến thức nền tảng về C/C++/Java.

  • Đầu tiên, Ruby loại bỏ những kí tự không cần thiết: () {};

    • Dấu ngoặc ở lời gọi hàm (method) không bắt buộc, ví dụ: puts "hi".
    • Không cần dấu chấm phẩy ở cuối mỗi dòng lệnh.
    • Sử dụng “if else end” hơn là sử dụng các dấu ngoặc nhọn {}.
    • Dấu ngoặc không cần thiết phải bao quanh điều kiện trong câu lệnh if else.
    • Method sẽ tự động trả về giá trị của dòng cuối cùng (có thể chỉ rõ bằng cách sử dụng return.

Ruby loại bỏ những yếu tố gây khó chịu như các dấu ngoặc, dấu chấm phẩy gây rất nhiều phiền nhiều, làm lập trình viên bị sao nhãng bởi logic của chương trình. Tại sao phải đặt dấu ngoặc ((xung quanh), (tất cả mọi thứ))? Thêm nữa, nếu bạn muốn sử dụng dấu ngoặc, cứ đưa chúng vào. Nhưng yên tâm, bạn sẽ sớm quen với cú pháp tiện dụng mới của Ruby thôi.

Những thứ dùng để ngắt câu như dấu chấm phẩy mà chúng ta sử dụng trong C hay Java với mục đích giúp đỡ trình biên dịch chứ không phải giúp đỡ chúng ta – lập trình viên. Với sự gọn gàng của Ruby, sau khi làm quen với Ruby một vài tuần, bạn sẽ thấy chán ngắt khi phải làm việc với những ngôn ngữ phức tạp khác.

  • Một số biến của Ruby

    • x = 3 là một biến dùng trong một method và chỉ trong method đó.
    • @x = 3 là biến thực thể (instance variable) sở hữu bởi mỗi đối tượng. (luôn luôn gắn với đối tượng đó).
    • @@x = 3 là biến của lớp (class variable) được dùng chung bởi tất cả các đối tượng (cũng gắn với đối tượng đó) (cái này mình cũng chỉ mới tìm hiểu ^.^).
    • :hello là một symbol, giống như một hằng ký tự.
    • dictionary = { :cat => "Goes meow", :dog => "Barks loud."} là một hash với cặp key/value.
  • Một số toán tử của Ruby

    • Ruby có toán tử || khá là "thú vị". Khi đặt nó vào một ràng buộc:
x = a || b || c || "default"

Nó có nghĩa là “kiểm tra từng giá trị một và trả về giá trị đầu tiên mà không sai”. Có nghĩa là nếu a sai, tìm b. Nếu b không có, thử c. Nếu không được nữa thì trả về string “default”.

Nếu bạn viết x = x || "default" nó có nghĩa là “Gán x bằng chính nó (nếu nó có một giá trị), nếu không thì gán default”. Một cách viết đơn giản hơn là:

x ||= "default"

  • Ngoài ra, Ruby còn có các block, proc, lambda. Đây gần như là các hàm của Ruby. Các bạn có thể xem thêm trong bài viết trước của mình tại đây.

3. Tiếp đến là phần tìm hiểu về Rails

Rails có những đặc thù khá khác biệt với các ngôn ngữ lập trình khác. Ví dụ như các Class và tên bảng, các chữ viết hoa ngăn cách giữa các từ để giúp việc gọi đối tượng từ các Class và bảng cơ sở dữ liệu dễ dàng hơn chẳng hạn.

Rất nhiều method có thể nhận các tùy chọn hash như là một tham số, hơn là việc có cả tá các tham số riêng lẻ. Ví dụ như khi bạn nhìn thấy:

<%= link_to “View Post”, :action => ‘show’, :controller => ‘article’, :id => @_article %>

Lời gọi này thực sự đang làm việc này:

<%= link_to("View Post", {:action => 'show', :controller => 'article', :id => @_article}) %>

Như các bạn đã thấy lời gọi này chỉ gồm 2 tham số. Đó là tên "View Post" và một hash {:action => 'show', :controller => 'article', :id => @_article} và với việc bỏ () đã nói ở trên thì code của chúng ta trở nên rất ngắn gọn phải không nào?

Một trong những đặc điểm của Rails là bạn bị buộc phải viết chương trình theo một loạt các quy tắc nhất định, tức là bạn phải theo mô hình kiến trúc mà Rails đã đề ra, tuy nhiên những quy tắc này lại khiến việc phát triển ứng dụng trở nên dễ dàng hơn rất nhiều. Và mô hình mà Rails sử dụng chính là MVC

4. Hiểu về mô hình Model-View-Control

Rails được xây dựng trên mô hình MVC và khá là dễ hiểu. Nói một cách đơn giản: mô hình này chia rõ ra các tầng dữ liệu(model), tầng hiển thị(View), tầng xử lý(Controller) của chương trình. Các tầng này liên kết, tương tác với nhau và điều này cũng giống như bạn chia rõ HTML, CSS, Javascript vậy.

Một cách cụ thể, có thể viết như sau:

  • Models là những lớp nói chuyện với cơ sở dữ liệu. Bạn có thể tìm kiếm, tạo mới và lưu các mô hình (model), nên bạn (thường) không hay phải viết SQL. Rails có lớp để xử lý việc lưu vào cơ sở dữ liệu khi một model được cập nhật. Thật kỳ diệu.
  • Controllers nhận đầu vào của người dùng và quyết định xem sẽ làm gì (hiển thị một trang, sắp xếp một item hay gửi một bình luận). Ban đầu chúng có thể có các logic như là tìm đúng model hay sửa đổi dữ liệu. Nhưng khi chương trình rails của bạn được cải thiện, liên tục refactor và chuyển các business logic vào model. Lý tưởng nhất, controllers chỉ nhận input, gọi model method và sau đó đưa output cho View (bao gồm cả thông báo lỗi).
  • Views hiển thị các output, thường là HTML. Chúng ta sử dụng ERB, giống như PHP, sử dụng HTML kèm thêm một chút code Ruby chèn thêm vào.

5. Tiếp đến là một chút về cấu trúc thư mục của Rails

Sau khi "rails new project_name" bạn sẽ thấy trên thư mục gốc của ứng dụng Rails đã tạo sẵn một danh sách các thư mục và tập tin cho bạn.

  • Thư mục app

    • controllers: các tập tin controller dùng để điều hướng luồng chạy của ứng dụng.

    • models: các tập tin models được dùng để tương tác với database trong ứng dụng (hoặc dùng để mô phỏng một đối tượng mà không cần kết nối tới database).

    • helpers: các tập tin helpers chứa các hàm (hoặc các lớp) hỗ trợ và được sử dụng bởi controllers, models hay views.

    • views: các tập tin views được sử dụng bởi controller dùng để hiển thị nội dung của trang.

    • mailers: bao gồm các template mẫu dùng để gửi email.

    • assets: bao gồm các tập tin như ảnh, css, javascripts...

Ngoài ra còn một sô folder khác mình sẽ làm một bài viết khác về vấn đề này.

  • Thư mục Components: Các components giống như một ứng dung mini và nó có thể chứa các models, views và controllers của riêng nó. (Cái này mình cũng chưa sử dụng bao giờ nên chỉ tìm hiểu được chút ít).
  • Thư mục Bin: Thư mục này bao gồm các đoạn mã script để khởi động ứng dụng Rails hoặc dùng để thiết lập hay deploy ứng dụng.
  • Thư mục Config: Thư mục này dùng để cấu hình ứng dụng như cấu hình các thông số của database, định nghĩa các routes...
  • Tập tin Config.ru: Tập tin này dùng để cấu hình cho Rack server nếu bán sử dụng Rack để chạy ứng dụng.
  • Thư Mục db: Thư mục này chứa các tập tin dùng để tạo cấu trúc schema cho database và các tập tin migrations.
  • Tập Tin Gemfile và Gemfile.lock: Tập tin Gemfile dùng để liệt kê những gem nào dùng trong ứng dụng và Gemfile.lock dùng để ghi lại thông tin về quá trình cài đặt các gem.
  • Thư mục Lib: Bao gồm các thư viện được dùng trong ứng dụng. Thông thường các thư viện này được viết bởi chính những lập trình viên tham gia vào viết ứng dụng. Các thư viện của bên thứ 3 thường không được đặt ở trong thư mục này mà sẽ để trong thư mục vendor mà mình sẽ đề cập ở phần dưới đây.
  • Thư mục Public: Nội dung của các tập tin đặt trong thư mục này sẽ có thể được tải trực tiếp về trình duyệt. Ví dụ ứng dụng của bạn được truy cập thông qua tên miền là hoclaptrinh.org thì khi bạn để một tập tin có tên là logo.png trong thư mục này, bạn có thể truy cập trực tiếp tập tin trên qua đường dẫn hoclaptrinh.org/logo.png. Thông thường chúng ta sẽ để chứa các tập tin css, javascript hay hình ảnh trong thư mục này.
  • Thư mục Vendor: Thư mục này chứa các thư viện của bên thứ 3 được sử dụng trong ứng dụng.

Trên đây là một số hiểu biết của mình về một Rails project.

Bài viết có tham khảo ở một số bài viết trên mạng và còn nhiều thiếu sót. Mong các bạn ủng hộ để bài viết thêm hữu ích hơn.

Cảm ơn mọi người đã quan tâm!