MỘT SỐ TIPS VÀ TRICKS RUBY ON RAILS CÓ THỂ BẠN CHƯA BIẾT
Trong bài viết này mình muốn chia sẻ với các bạn một số tính năng của Ruby và Rails có thể bạn đã biết hoặc chưa biết. Một số nội dung chỉ là những thay đổi mới xuất hiện với các phiên bản Ruby hoặc Rails mới. Hãy cùng tìm hiểu nhé Tạo Hash với list các values Bạn có thể tạo một Hash từ danh ...
Trong bài viết này mình muốn chia sẻ với các bạn một số tính năng của Ruby và Rails có thể bạn đã biết hoặc chưa biết. Một số nội dung chỉ là những thay đổi mới xuất hiện với các phiên bản Ruby hoặc Rails mới. Hãy cùng tìm hiểu nhé
Tạo Hash với list các values
Bạn có thể tạo một Hash từ danh sách các giá trị bằng cách sử dụng Hash [...]. Nó sẽ tạo ra một Hash như dưới đây:
Hash['key1', 'value1', 'key2', 'value2'] => {"key1"=>"value1", "key2"=>"value2"}
Lambda viết tắt là ->
Dấu -> được sử dụng thường xuyên để thay thế cho Lambda.
a = -> { 1 + 1 } a.call # => 2 a = -> (v) { v + 1 } a.call(2) # => 3
Double star (**)
Double star là một mẹo nhỏ trong Ruby. Mời các bạn xem ví dụ sau để hiểu thêm chi tiết:
def my_method(a, *b, **c) return a, b, c end
a sẽ là tham số thông thường, b sẽ lấy tất cả các tham số được truyền vào sau giá trị đầu tiên và đặt chúng vào một mảng, c sẽ lấy bất kỳ tham số nào có định dạng key: value ở cuối phương thức.
Hãy quan sát ví dụ dưới đây:
Truyền vào một tham số:
my_method(1) # => [1, [], {}]
Truyền vào nhiều tham số:
my_method(1, 2, 3, 4) # => [1, [2, 3, 4], {}]
Truyền vào nhiều tham số + tham số dạng hash:
my_method(1, 2, 3, 4, a: 1, b: 2) # => [1, [2, 3, 4], {:a=>1, :b=>2}]
Xử lý đối tượng đơn lẻ và mảng theo cùng một cách
Đôi khi bạn có thể muốn cung cấp tùy chọn chấp nhận một đối tượng hoặc một mảng đối tượng. Thay vì kiểm tra loại đối tượng bạn đã nhận được, bạn có thể sử dụng [* something] hoặc Array (something).
Hãy gán hai biến. Biến đầu tiên là một số và biến thứ hai là một dãy số.
stuff = 1 stuff_arr = [1, 2, 3]
Ví dụ sau sử dụng [* ...] để lặp qua bất kỳ thứ gì được đưa ra.
[*stuff].each { |s| s } [*stuff_arr].each { |s| s }
Tương tự như vậy nhưng sử dụng Array (...).
Array(stuff).each { |s| s } Array(stuff_arr).each { |s| s }
Double Pipe Equals ||=
Double Pipe Equals là một công cụ tuyệt vời để viết mã ngắn gọn và súc tích.
Khi viết a ||= b thì nó tương đương với:
a || a = b # Correct
Chứ không phải như nhiều người nghĩ là:
a = a || b # Wrong
Toán tử này có thể được sử dụng để tạo các phương thức như thế này trong các class của bạn như là sử dụng nó để tính toán.
def total @total ||= (1..100000000).to_a.inject(:+) end
Bây giờ bạn có thể có gọi phương thức total để nhận được tổng giá trị, nhưng nó sẽ chỉ được tính duy nhất vào lần đầu tiên.
Tham số Hash bắt buộc
Điều này đã được giới thiệu từ Ruby 2.0. Thay vì chỉ định nghĩa một phương thức nhận tham số là Hash như sau:
def my_method({}) end
Bạn có thể chỉ định các keys mà bạn mong muốn và thậm chí có thể định nghĩa giá trị mặc định cho chúng! a và b là các khóa bắt buộc, c là từ khóa mặc định.
def my_method(a:, b:, c: 'default') return a, b, c end
Chúng ta có thể thử gọi nó mà không truyền giá trị cho tham số b, nó sẽ không hoạt động.
my_method(a: 1) # => ArgumentError: missing keyword: b
Vì c có giá trị mặc định, nên chúng ta có thể gọi phương thức với a và b mà k cần truyền tham số c.
my_method(a: 1, b: 2) # => [1, 2, "default"]
Hoặc với toàn bộ tham số:
my_method(a: 1, b: 2, c: 3) # => [1, 2, 3]
Và đương nhiên chúng ta có thể truyền trực tiếp 1 Hash trực tiếp vào phương thức này:
hash = { a: 1, b: 2, c: 3 } my_method(hash) # => [1, 2, 3]
Tạo mảng bảng chữ cái hoặc số
Bạn có thể muốn tạo một danh sách các số hoặc đặt toàn bộ bảng chữ cái bên trong một mảng. Trong Ruby bạn có thể sử dụng ranges để làm điều đó. A to Z
('a'..'z').to_a # => ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
1 đến 10
(1..10).to_a # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Tap
Tap là một phương thức nhỏ giúp code của bạn dễ đọc hơn cũng như tránh trùng lặp code. Hãy theo dõi ví dụ dưới đây để biết thêm chi tiết:
class User attr_accessor :a, :b, :c end
Bây giờ, giả sử bạn muốn khởi tạo một người dùng mới và chỉ định giá trị cho từng thuộc tính của người dùng đó. Bạn có thể làm như sau:
def my_method o = User.new o.a = 1 o.b = 2 o.c = 3 o end
Hoặc bạn có thể sử dụng Tap để làm điều đó như thế này.
def my_method User.new.tap do |o| o.a = 1 o.b = 2 o.c = 3 end end
Giá trị mặc định cho Hash (Bad trick)
Theo mặc định, khi cố gắng truy cập một giá trị không được định nghĩa trong một Hash, bạn sẽ nhận được nil. Bạn có thể thay đổi điều này khi khởi tạo Hash.
Đừng bao giờ làm điều này trừ khi bạn biết chính xác mình điều đang làm là cần thiết.
Trong ví dụ đầu tiên, a xác định giá trị mặc định là 0 vì vậy khi a[:a] được gọi, chúng ta sẽ lấy được giá trị là 0 chứ không phải nil.
a = Hash.new(0) a[:a] # => 0
Chúng ta có thể truyền bất cứ thứ gì khi khởi tạo Hash. Hãy thử với một Hash!
a = Hash.new({}) a[:a] # => {}
Hoặc một chuỗi:
a = Hash.new('lolcat') a[:a] # => "lolcat"
Hash#dig
Đã bao nhiêu lần bạn làm một cái gì đó tương tự như thế này:
... if params[:user] && params[:user][:address] && params[:user][:address][:somewhere_deep]
Dig tương tự như &. cho Hash Object. Vì vậy, bạn có thể viết lại đoạn code phức tạp trên thành:
... if params.dig(:user, :address, :somewhere_deep)
Object#presence_in
Nó cho phép bạn thay thế các điều kiện (thường là ternary) bằng cách gọi một phương thức đơn giản. Ví dụ: Code của bạn trông như sau:
sort_options = [:by_date, :by_title, :by_author] ... sort = sort_options.include?(params[:sort]) ? params[:sort] : :by_date # Another option sort = (sort_options.include?(params[:sort]) && params[:sort]) || :by_date
Chuyển thành thế này nhìn có tuyệt hơn không?
params[:sort].presence_in(sort_options) || :by_date
Trên đây là những mẹo nhỏ khi code ruby và rails hi vọng giúp ích được cho các bạn trong quá trình lập trình.
NGUỒN THAM KHẢO
https://devblast.com/b/ruby-tricks-improve-code
https://hackernoon.com/5-ruby-on-rails-tips-you-probably-dont-know-8b80b4a0890f