5 Câu hỏi vui về Ruby on Rails
Bài đăng này đã không được cập nhật trong 6 năm
11 Câu hỏi vui về Ruby on Rails
1. Sử dụng ActiveSupport::Concern
Vấn đề được đưa rả ở đây là: Khi một đối tượng của bạn được tạo ra, nhưng có rất nhiều mối quan hệ với các đối tượng khác trước đó, có nhiều function được dùng liên quan tới nó.
VD: Một đối tượng User
, Post
, Like
được tạo ra, và đối tượng user được nhắc đến ở cả 2 bảng đối tượng Post
& Like
thông qua attr
created_by_id
.
Khi đó chúng ta nhận ra rằng cả 2 đối tượng User
vs Post
đều cần dùng tới một thuộc tính chung là:
belongs_to :created_by, class_name: User, foreign_key: :created_by_id
Đây là lúc chúng ta dùng tới ActiveSupport::Concern
.
require 'active_support/concern'
module Concerns::Userable
extend ActiveSupport::Concern
included do
belongs_to :created_by, class_name: User, foreign_key: :created_by_id
end
end
và trong 2 model của Post
& Like
chúng ta chỉ cần thêm như sau:
class Post < ActiveRecord::Base
include Concerns::Userable
end
class Like < ActiveRecord::Base
include Concerns::Userable
end
Ưu điểm:
trong phương pháp này chúng ta có thể tránh đượcDRY
code trong 2 model. Dễ sửa chữa những phần chung giữa 2 model.Nhược điểm:
Tuy nhiên phương pháp này cũng có 1 nhược điểm là khi chúng ta lạm dụng cách này quá nhiều dự án của chúng ta sẽ có số lượng file tăng 1 các khổng lồ, có thể dẫn tới khó đọc + debug trong quá trình sau này.
2. Service object
Delegate cùng là 1 phần mình được học từ khi bắt đầu với ruby. Nó giúp giải quyết những vấn đề riêng biệt có tính chuyên môn riêng cho từng đối tượng.
Ví dụ được đưa ra ở đây là: giả sử với 2 đối tượng Blog
, Like
như trên, bây giờ có 1 yêu cầu update lại tất cả created_by
trong 2 đổi tượng trên.
Khi nhận yêu cầu bạn sẽ nghĩ khi controller gọi đến nó thì tương luôn trong controller và gọi đến Blog.update_all: created_by: user_id
.
Vẫn ngon =)). Tuy nhiên giờ lại có 1 yêu cầu mới là: "tao chỉ muốn sửa created_by của 1 số thằng thôi!!" Thôi lại sửa rồi.
khí đó mình nghĩ nó là 1 chức năng riêng rồi, và được dùng lại > 1 lần rồi vậy có thể cho vao module như trên nhỉ. Hoặc có 1 cách khác bạn có thể dùng đến service object trong ruby:(phần này được hướng dẫn rất nhiều trên viblo).
3. Cho 1 mảng số và tính tổng?
[1,2,3, 4,5,6,7,8,9]
câu hỏi quá đơn giản khi nhận được chúng ta có rất nhiều cách.
Cách 1: duyệt vòng for chạy từ đàu đến cuối mảng và cộng thêm vào biến tổng.
Cách 2: sử dụng inject
trong ruby: array.inject(:+)
Cách 3: đơn giản nhất gọi luôn hàm sum trong ruby: array.sum
rất nhiều cách làm với câu hỏi này, tuy nhiên hãy chọn cách làm nhanh nhất và phù hợp nhất để đạt mục đích.
4. metaprogramming là gì?
câu này hơi cao siêu rồi, lúc đầu mình nghe chằng biết nó là cái gì cả và mãi mới nhớ tên + đọc hiểu code do thằng nào đó viết theo lối này rất khó chịu. Tuy nhiên nó lại là thứ đang được dùng rất nhiều trong ruby.
metaprogramming
: theo mình gọi thì nó là: code sinh ra code
.
Vâng khó hiểu quá. Chúng ta đi tới:
VD:
giả sử User
trên chúng ta có 1 trường là role
và càn check quyền của nó. trong khi đó role có các quyền như: :admin, :edit, :reading
và cần check quyền này. Khi đó chúng ta sẽ có đoạn code sau:
def admin?
role == 'admin'
end
def edit?
role == 'edit'
end
def reading?
role == 'reading'
end
chuẩn rồi tuy nhiên để tránh DRY code thì metaprograming sẽ có thể giải quyết được như code:
['admin', 'edit', 'reading'].each do |role|
define_method "#{role}?" do
role == role
end
end
đơn giản nhưng khó hiểu.
5. Instance method, Class method & private method?
3 thành phần được dùng rất nhiều của một đối tượng mà thường thì mình rất để ý đến(chỉ dùng thôi).
Chúng ta có vi dụ sau:
class User
def talk
puts about
end
private
def about
"Tôi là 1 user"
end
class << self
def talk
puts "Tao là 1 user"
end
end
end
Vâng đối với User
trên chúng ta gọi bằng cách sau sẽ có kết quả khác nhau:
User.new.talk => Tôi là 1 user
User.talk => Tao là 1 user
User.new.about => NoMethodError: private method
User.about => NoMethodError: undefined method
Với câu thư 1: chúng ta biêt được rằng chúng ta gọi đến method talk
với vai trò là 1 Instance method
nó là 1 thuộc tính của đối tượng.
Với câu thư 2: cũng gọi đến talk
tuy nhiên thằng được gọi đến lại không phải là một thuộc tính của đối tượng mà nó là 1 Class method
.
Với câu thư 3, 4: nó thì không được hiều là cái gì cả vì chúng ta không thể gọi từ bên ngoài mà gọi được 1 function private.
Tuy nhiên ruby có hàm hỗ trợ đó là send || try
(Bạn nên hạn chế dùng 2 thuộc tính này nếu không bắt buộc) . 2 method send & try
thường được dùng trong phần 4 metaprogramming
.
Kết:
Bài này mình lấy ý tưởng từ trang codementor và viết trên sự hiểu biết của mình. Trong đó còn 1 số câu rất thú vị hi vọng mọi người có thê đoc. Rất cảm ơn.
All rights reserved