Repository Pattern in Rails
Bài đăng này đã không được cập nhật trong 7 năm
Gần đây mình có tìm hiểu về Ruby on Rails, trước đó mình code PHP trên framework Laravel. Những ai làm Laravel thì chắc quen với Repository Pattern. Repository là một phong cách thiết kế code thực hiện việc tách biệt giữa data access logic và business logic, nó được thực hiện bằng cách thêm vào một tầng nằm giữa Business Logic và Data Source, gọi là các Repository - nơi lưu trữ tất cả code liên quan đến việc truy cập dữ liệu. Khi nhảy vào học Rails, mình cũng tìm hiểu ngay về vấn đề này. Bài viết hôm nay mình sẽ demo nho nhỏ về Repository trong Rails. Bây giờ chúng ta hãy cùng xem một action create quen thuộc dưới đây nhé
def create
@user = User.new(user_params)
if @user.save
redirect_to user_path(@user), notice: 'User has been created'
else
render :new
end
end
Rất là quen thuộc phải không các bạn. Còn có thêm protecting attributes user_params nữa nhưng mình không cho vào, chắc các bạn cũng biết rồi. Mà mình thấy lúc trước có thể dùng attr_accessible mà không rõ lý do gì mà nó lại bị khai tử và bắt mình phải viết thêm method user_params nựa, hay họ sợ developer nhầm lẫn giữa attr_accessible và attr_accessor chăng, thôi kệ đi. Bây giờ chúng ta sẽ tiến hành tách ra bằng việc sử dụng Repository pattern để trừu tượng hóa cách tương tác với cơ sở dữ liệu. Các bạn hãy tạo lớp UserRepository trong thư mục app/repositories chịu trách nhiệm tương tác với cơ sở dữ liệu nhé.
class UserRepository
def all
User.all
end
def find(id)
User.find(id)
end
def new_entity(attrs = nil)
User.new(attrs)
end
def save(user)
user.save
end
def delete(user)
user.destroy
end
end
Bây giờ thì bạn có thể sử dụng trong controller rồi
class UsersController < ApplicationController
before_action :set_user, only: [:edit, :show]
def show
end
def create
@user = repo.new_entity(user_params)
if repo.save(@user)
redirect_to user_path(@user), notice: 'User has been created'
else
render :new
end
end
def edit
end
private
def set_user
@user = repo.find(params[:id])
end
def user_params
params.require(:user).permit(:first_name, :last_name, :password)
end
def repo
@repo ||= UserRepository.new
end
end
Việc sử dụng Repository đem lại một số lợi ích sau:
- Chúng ta không phải tương tác trực tiếp mới model trong controller nữa.
- Cấu trúc code dễ nhìn và dễ hiểu
- Code dễ đọc hơn, chúng ta chỉ cần focus vào data access logic nên khi có thay đổi gì thì cũng sẽ dễ dàng hơn trong việc maintain code.
Để triễn khai đúng Repository Pattern thì bạn cần phải tạo ra BaseRepository và định nghĩa các method thường được sử dụng trong lớp này, ứng với mỗi model thì ta sẽ tạo ModelNameRepository kế thừa từ BaseRepository. ModelNameRepository chỉ cần định nghĩa thêm những phương thức của riêng nó, còn các phương thức cơ bản như find, all.. đã có trong Base rồi. Việc làm này nhằm tăng tính tái sử dụng và giảm thiểu trùng lặp code.
Trên đây là những chia sẽ của mình về cách sử dụng Repository trong Rails, hi vọng nó sẽ hữu ích cho các bạn.
All rights reserved