Trong bài viết này mình sẽ giới thiệu với các bạn một số method hay và thú vị hay dùng trong Rails.

Sử dụng blank?/present?

    # String
    user = nil
    user.blank? # => true
    user = ""
    user.blank? # => true
    user = " "
    user.blank? # => true
    user = "Tung"
    user.blank? # => false

    # Array
    numbers = nil
    numbers.blank? # => true
    numbers = []
    numbers.blank? # => true
    numbers = [1, 2, 3]
    numbers.blank? # => false

    # Hash
    params = nil
    params.blank? # => true
    params = {}
    params.blank? # => true
    params = { name: "Tung", email: "pham.van.tung@framgia.com" }
    params.blank? # => false

present? ngược lại với blank?.

    # String
    name = ""
    name.present? # => false
    name = "Tung"
    name.present? # => true

Sử dụng presence

    if user.name.blank?
      name = "What's your name?"
    else
      name = user.name
    end
    name = user.name.presence || "What's your name?"

"".presence hoặc [].presence sẽ trả về nil

    name = ""
    puts name.presence || "What's your name?" # => What's your name?

À có 1 ví dụ rất thú vị về presence như sau.

    # News nếu có ít nhất là 1 news thì gửi mail và tweet
    news = festival.news
    if news.count > 0
      send_mail(news)
      tweet(news)
    end

Nếu dùng presence

    if news = festival.news.presence
      send_mail(news)
      tweet(news)
    end

festival.news trả về kết quả 0 thì festival.news.presence sẽ trả về là nil. Khi đó câu lệnh if sẽ xử lý false.

Kiểm tra sự tồn tại của 1 string thì nên dùng blank? thay vì nil?

Mệnh đề “string không có giá trị” thường không cần phân biệt nil và "". Khi sử dụng nil? thì lại cho 2 kết quả khác nhau.

    if name.nil?
      # => nếu name là "" thì vẫn được coi là có nhập dữ liệu và không gọi puts
      puts "Please input name!"
    end

Đó cũng là lý do nên sử dụng blank? hơn. ruby if name.blank? # => Nếu name là "" hoặc " " thì xử lý như chưa nhập dữ liệu và gọi puts puts "Please input name!" end

Tương tự như thế, khi validates trong Model, nếu không có lý do đặc biệt thì nên sử dụng allow_blank: true, không nên sử dụng allow_nil: true.

Khi cần filter, nên dùng query thay vì logic

Khi cần thực hiện filter trong model của Rails, thì nên sử dụng query để tốc độ xử lý được nhanh hơn.

    def admin_users
      User.all.select(&:admin?)
    end
    def admin_users
      User.where(admin: true)
    end

Dùng pluck thay vì map

pluck là method để lấy 1 column cho trước trong record, mà không load toàn bộ record đó. Vì thế mà tốc độ xử lý cũng sẽ hiệu quả hơn.

    def admin_user_ids
      User.where(admin: true).map(&:id)
    end
    def admin_user_ids
      User.where(admin: true).pluck(:id)
    end

Dùng Object#try(:method_name) thay vì kiểm tra nil

    if person.books && person.books.singleton?
      singleton = person.books.first
      send_mail_to(singleton)
    end
    # nếu books là nil thì try(:singleton?) cũng trả về nil
    # nếu books không nil thì books.singleton? được gọi như bình thường
    if person.books.try(:singleton?)
      singleton = person.books.first
      send_mail_to(singleton)
    end

Một số method thời gian hay

    Date.current # => Sun, 29 May 2016

    Date.yesterday  # => Sat, 28 May 2016
    Date.tomorrow # =>  # => Mon, 30 May 2016
    Date.current # => 2013-11-05

    2.years.ago   # => 2014-05-29 22:21:40 +0700
    2.years.since # => 2018-05-29 22:21:40 +0700

    2.months.ago   # => 2016-03-29 22:21:40 +0700
    2.months.since # => 2016-07-29 22:21:40 +0700

Weeks, days, hours, minutes, seconds cũng thế.

Ngoài ra còn rất nhiều cách viết khác nhau để lấy giá trị ngày tháng đặc biệt.

    date = Date.current # => 2016-05-29

    date.yesterday # => 2016-05-28
    date.tomoroow  # => 2016-05-30

    date.prev_day # => 2016-05-28
    date.next_day # => 2016-05-30

    date.prev_day(2) # => 2016-05-27
    date.next_day(2) # => 2016-05-31

    date - 2.days # => 2016-05-27
    date + 2.days # => 2016-05-31

    date.ago(2.days)   # =>  2016-05-27
    date.since(2.days) # =>  2016-05-31

    date.prev_month # =>  2016-04-29
    date.next_month # =>  2016-06-29

    date.prev_month(2) # => 2016-03-29
    date.next_month(2) # => 2016-07-29

    date - 2.months # => 2016-03-29
    date + 2.months # => 2016-07-29

    date.months_ago(2)   # => 2016-03-29
    date.months_since(2) # => 2016-07-29

    date.ago(2.months)   # => 2016-03-29
    date.since(2.months) # => 2016-07-29

Xoá các space không cần thiết

"    My    \r\n  \t   \n   books       ".squish # => "My books"

Các method thay đổi string thành số nhiều, số ít, …

    "my_book".camelize # => "MyBook"

    "MyBook".underscore # => "my_book"

    "my_book".dasherize # => "my-book"

    "book".pluralize            # => "books"
    "person".pluralize          # => "people"
    "fish".pluralize            # => "fish"
    "book_and_person".pluralize # => "book_and_people"
    "book and person".pluralize # => "book and people"
    "BookAndPerson".pluralize   # => "BookAndPeople"

    "books".singularize            # => "book"
    "people".singularize           # => "person"
    "books_and_people".singularize # => "books_and_person"
    "books and people".singularize # => "books and person"
    "BooksAndPeople".singularize   # => "BooksAndPerson"

    "my_books".humanize # => "My books"

    "my_books".titleize # => "My Books"

    "my_book".classify  # => "MyBook"
    "my_books".classify # => "MyBook"

    "my_book".tableize # => "my_books"
    "MyBook".tableize  # => "my_books"

Hy vọng sẽ giúp các bạn yêu thích và tiếp cận Rails dễ dàng hơn.