12/08/2018, 13:33

ActiveSupport trong Rails

Giới thiệu Sau khi cài đặt một ứng dụng rails chúng ta sẽ thấy có một số thư viện sau được cài kèm theo. $ gem list actionmailer ( 4.2 .6 , 4.2 .4 ) actionpack ( 4.2 .6 , 4.2 .4 ) actionview ( 4.2 .6 , 4.2 .4 ) activejob ( 4.2 .6 , 4.2 .4 ) activemodel ( ...

Giới thiệu

Sau khi cài đặt một ứng dụng rails chúng ta sẽ thấy có một số thư viện sau được cài kèm theo.

$ gem list

actionmailer (4.2.6, 4.2.4)
actionpack (4.2.6, 4.2.4)
actionview (4.2.6, 4.2.4)
activejob (4.2.6, 4.2.4)
activemodel (4.2.6, 4.2.4)
activerecord (4.2.6, 4.2.4)
activesupport (4.2.6, 4.2.4)
...

Hôm nay chúng ta sẽ cùng tìm hiểu về thư viện ActiveSupport trong rails.

ActiveSupport là gì?

ActiveSupport là một thành phần của Ruby on Rails được cung cấp nhằm mục đích mở rộng ngôn ngữ Ruby

Active Support is the Ruby on Rails component responsible for providing Ruby language extensions, utilities, and other transversal stuff. It offers a richer bottom-line at the language level, targeted both at the development of Rails applications, and at the development of Ruby on Rails itself.

Có nghĩa ActiveSupport là tập hợp các hàm tiện ích được Rails nhúng thẳng vào lớp của thư viện chuẩn của Ruby (như Array, String). Nhờ tính năng reopen của Ruby, việc nhúng này rất dễ dàng, mang lại cảm giác các hàm này có sẵn trong bản thân ngôn ngữ.

Các tiện ích trong ActiveSupport quá hay, đến nỗi nhiều người cứ tưởng các chúng là tính năng của Ruby, góp phần tạo nên triệu chứng biết Rails mà không biết Ruby!

Với document của ActiveSupport, ta sẽ tìm thấy rất nhiều thứ thú vị. Để dùng các hàm này trong chương trình Ruby bình thường (không phải là Rails), chúng ta chỉ cần require 'activesupport'.

Ví dụ một số hàm tiện ích của ActiveSupport

Vào rails console, chúng ta sử dụng luôn mà không cần require `activesupport

1. Chuyển đổi string

Khi đặt tên function hay tên biến, chúng ta cần chú ý đến việc số ít hay số nhiều để có thể thể hiện được ý nghĩa của nội dung bên trong. Hay cần định dạng, chuyển đồi các chuỗi về format thích hợp

"post".pluralize             # => "posts"
"octopus".pluralize          # => "octopi"
"sheep".pluralize            # => "sheep"
"words".pluralize            # => "words"
"the blue mailman".pluralize # => "the blue mailmen"
"elves".singularize          # => "elf"
"christmas_carol".camelize   # => "ChristmasCarol"
"christmas_carol".camelize(:lower) #=> "christmasCarol"
"holiday_cheer".titleize     # =>"Holiday Cheer"
"AdventCalendar-2006".underscore # => "advent_calendar_2006"
"santa_Claus".dasherize      # => "santa-Claus"
"Holiday::December::Christmas".demodulize #=> "Christmas"
"SnowStorm".tableize         # => "snow_storms"
"snow_storms".classify       # => "SnowStorm"
"present_id".humanize        # => "Present"
"Present".foreign_key        # => "present_id"
"Cheer".constantize          # => NameError: uninitialized constant Cheer
"Christmas".constantize      #=> Christmas

2. reverse_merge (Hash)

>> colors = { :foreground => 'red', :background => 'black' }
=> {:background=>"black", :foreground=>"red"}
>> colors.merge(:background => 'green')
=> {:background=>"green", :foreground=>"red"}

# doesn't override our set colors but would add in :background
# if we didn't already have it:
>> colors.reverse_merge(:background => 'green')
=> {:background=>"black", :foreground=>"red"}

3. Tính số byte (Number)

2.6.megabytes  # => 2726297.6

4. Chuyển mảng thành câu

%w[a b c].to_sentence                            # => "a, b, and c"
%w[a b c].to_sentence(:connector => '&')         # => "a, b, & c"
%w[a b c].to_sentence(:skip_last_comma => true)  # => "a, b and c"

5. blank? (Object)

Trong code, thay vì viết

if address.nil? && address.empty?

Sẽ được viết ngắn thành

if address.blank?
0.blank?           # => false
" ".blank?         # => true
[].blank?          # => true
{}.blank?          # => true
nil.blank?         # => true

Còn về sự khác nhau, hay cách dùng blank?, nil? và empty? cho từng trường hợp cụ thể thì sẽ có một bài khác nói về điều này.

6. attr_accessor_with_default

class Homework
  # Đỡ phải viết hàm khởi tạo
  attr_accessor_with_default :sucks, true
end
assignment = Homework.new
assignment.sucks => true

7. cattr*, mattr*, class_inheritable_accessor

Chắc hẳn chúng ta đã quen với, attr_accessor hay attr_reader hay attr_writer của Ruby. ActiveSupport cung cấp thêm cattr_accessor để khai báo accessor cho lớp.

cattr_accessor tạo ra một biến chung cho tất cả lớp cùng cây thừa kế, còn class_inheritable_accessor tạo biến riêng cho từng lớp.

class P1
  cattr_accessor :val
end

class C1 < P1
end

P1.val      # => nil
C1.val      # => nil
P1.val = 8
C1.val      # => 8

class P2
  class_inheritable_accessor :val
end

class C2 < P2
end

P2.val      # => nil
C2.val      # => nil
P2.val = 8
C2.val      # => nil

8. Returning (Object)

Giúp mã sáng sủa hơn vì làm rõ giá trị trả về là gì. Chúng ta cùng so sánh 2 đoạn mã sau.

def change_state object_id, new_state
  object = find object_id
  object.state = new_state
  object.save
  object
end

def change_state object_id, new_state
  returning find(object_id) do |object|
    object.state = new_state
    object.save
  end
end

Với returning, ban đầu ta khởi tạo đối tượng sẽ trả về, rồi sửa dần dần nó cho đến khi được cái ưng ý.

9

Kết luận

Trên đây chỉ là phần tìm hiểu và giới thiệu một số hàm cơ bản của ActiveSupport. Để tìm hiểu kỹ hơn, các bạn có thể truy cập vào document để biết thêm chi tiết cụ thể.

Tham khảo

http://errtheblog.com/posts/42-rails-rubyisms-advent

http://kipalog.com/posts/ActiveSupport--Vu-khi-bi-mat-cua-Rails

0