Rails read_attributes

Đăng bởi Lưu Đại vào ngày 18-12-2022

Vấn đề

Mình có 1 bảng department trong database và 1 model Department (id, name, department_group_id) tương ứng trong code Rails mỗi một department này thuộc 1 nhóm department_group (id, name). Mình muốn lấy ra tên của department trong trường hợp department không có tên thì sẽ lấy tên của department_group thay thế. 

Giải quyết 

Ban đầu mình viết đè hàm name trong model như sau
def name 
	name || group_department.name
end
Tuy nhiên cách này sẽ gọi đệ quy hàm name ⇒ lỗi. Nên mình research trên mạng và tìm được hàm read_attribute
def name 
	read_attribute(:name) || group_department.name
end
Nhìn vào source code của attr_name
# File activerecord/lib/active_record/attribute_methods.rb, line 272
def read_attribute(attr_name)
  attr_name = attr_name.to_s
  if !(value = @attributes[attr_name]).nil?
    if column = column_for_attribute(attr_name)
      if unserializable_attribute?(attr_name, column)
        unserialize_attribute(attr_name)
      else
        column.type_cast(value)
      end
    else
      value
    end
  else
    nil
  end
end
Hàm này sẽ trả về nil nếu không tồn tại attribute.

Chú ý

Một điểm chú ý nữa là khi department không có name mặc định thì nó sẽ tạo một query vào group_department (đặc biệt là trong những trường hợp lấy list equipment name). Nên phải includes group_department để tránh bị nhiều query.