Callbacks trong Rails
Bài đăng này đã không được cập nhật trong 5 năm
Trong quá trình xây dựng ứng dụng Rails thì chúng ta làm việc với các đối tượng.
Active Record cung cấp cho chúng ta Callbacks có thể chạy trước sau vòng đời của một đối tượng khi có sự thay đổi trạng thái như tạo, cập nhật, xóa... Nó có thể gọi bất kì lúc nào với action nào tùy vào cách gọi và mục đích sử dụng của chúng ta.
Sử dụng Callbacks
Để sử dụng Callback thì ta phải sử dụng chúng, ví dụ ta có 1 model user.rb như thế này.
class User < ApplicationRecord
before_save :downcase_email
private
def downcase_email
email.downcase!
end
end
Callbacks trên như là trước mỗi khi chúng ta lưu trường email vào table users thì phải downcase email.
Ta có thể gọi nó định nghĩa trong 1 block như là:
class User < ApplicationRecord
before_save do
self.email = email.downcase!
end
end
Hoặc là có thể giới hạn cho nó vòng đời nhất định nào đó như là:
class User < ApplicationRecord
before_validation :downcase_email, on: [:create, :update]
#before_validation :downcase_email, on: :create
private
def downcase_email
self.email = email.downcase!
end
end
Callbacks
Sau đây là danh sách một số callbacks theo vòng đời theo chức năng được định nghĩa tương ứng.
Creating:
- before_validation
- after_validation
- before_save
- around_save
- before_create
- around_create
- after_create
- after_save
- after_commit/after_rollback
Updating:
- before_validation
- after_validation
- before_save
- around_save
- before_update
- around_update
- after_update
- after_save
- after_commit/after_rollback
Destroying:
- before_destroy
- around_destroy
- after_destroy
- after_commit/after_rollback
Như ta thấy thì cả tạo và cập nhật đối tượng đều có những callback dạng như before_save thì tức nghĩa là nó bao gồm cả before_create và before_update.
after_touch
Callback after_touch sẽ hoạt động khi bất cứ hoạt động nào tác động.
class User < ApplicationRecord
after_touch do |user|
puts "DepZaiKhoQuaMoiNguoiOi"
end
end
>> = User.create(name: 'xnxx')
=> #<User id: 1, name: "Xnxx", created_at: "2019-10-18 21:17:49", updated_at: "2019-10-18 21:17:49">
>> user.touch
DepZaiKhoQuaMoiNguoiOi
=> true
Có thể dùng chung với belongs_to
class Employee < ApplicationRecord
belongs_to :company, touch: true
after_touch do
puts 'DepZaiKhoQuaMoiNguoiOi'
end
end
class Company < ApplicationRecord
has_many :employees
after_touch :log_when_employees_or_company_touched
private
def log_when_employees_or_company_touched
puts 'Locdeptrai'
end
end
>> @employee = Employee.last
=> #<Employee id: 1, company_id: 1, created_at: "2019-10-18 21:17:49", updated_at: "2019-10-18 21:17:49">
>> @employee.touch
DepZaiKhoQuaMoiNguoiOi
Locdeptrai
=> true
Callback trong relationship
Giả sử có 2 đối tượng là User và Article(1-n). Callbacks hoạt động thông qua relationship và thậm chí có thể được xác định bởi chúng. Giả sử một ví dụ trong đó User có nhiều Article. Article của người dùng nên bị xóa nếu User bị xóa. Ta thêm một callback after_destroy cho model User bằng mối quan hệ của nó với model Article:
class User < ApplicationRecord
has_many :articles, dependent: :destroy
end
class Article < ApplicationRecord
after_destroy :log_destroy_action
def log_destroy_action
puts 'Article đã được xóa'
end
end
>> user = User.first
=> #<User id: 1>
>> user.articles.create!
=> #<Article id: 1, user_id: 1>
>> user.destroy
Article đã được xóa
=> #<User id: 1>
Kết
Trên đây mình chia sẻ về một số vấn đề cơ bản về Callbacks trong rails, còn nhiều thứ vân vân mây mây mà có lẽ mình chưa sử dụng bao giờ. Hy vọng bài viết tìm hiểu từ 1 số nguồn và mình đã biên tập lại theo cách hiểu của mình sẽ giúp ích cho một số bạn chưa biết. Cám ơn các bạn đã đọc bài viết của mình./.
All rights reserved