Tìm hiểu Nested Attributes trong Rails

Tram Ho

1. Khái niệm

Nested attibutes là một tính năng của Active Record, hỗ trợ tạo mới bản ghi thông qua bản ghi cha của nó. Mặc định tính năng không được kích hoạt, muốn sử dụng chúng ta phải khai báo trong Model muốn thực hiện. Kích hoạt nó bằng phương thức: accepts_nested_attributes_for

accepts_nested_attributes_for :model_name ở ví dụ trên sẽ tạo ra 2 phương thức mới: author_attributes=(attributes)pages_attributes=(attributes)

Option :autosave sẽ tự động được bật trên mọi liên kết mà accepts_nested_attributes_for được sử dụng

2. Cách sử dụng

2.1. Quan hệ 1-1

=> Chỉ tạo được duy nhất 1 lần trong mối quan hệ 1-1

=> Cũng có thể cập nhật bản ghi con avatar thông qua member, lưu ý bản ghi cha phải được save thì bản ghi con mới được save

=> Nếu bạn muốn update avatar mà không cần cung cấp :id thì phải thêm option :update_only

=> Mặc định chỉ cho createupdate trên model liên kết, nếu bạn muốn destroy thông qua bản ghi cha thì trước tiên ta cần thêm option :alow_destroy, sau đó thêm _destroy vào attributes hash, với value là truethì ta sẽ hủy được bản ghi con.

Bản ghi con sẽ không được destroy nếu bạn ghi cha chưa được lưu

2.2. Quan hệ 1-n

=> Đối với mỗi hàm băm không có khóa :id, một bản ghi mới sẽ được khởi tạo, trừ khi hàm băm cũng chứa khóa_destroy :true

=> Chúng ta cũng có thể đặt option :reject_if proc để bỏ qua bất kỳ hàm băm bản ghi mới nào nếu chúng không đạt yêu cầu do mình đề ra. Với ví dụ trên

=> một số cách khác khi dùng với :reject_if

=> Nếu hash chứa khóa :id khớp với bản ghi đã được liên kết, bản ghi phù hợp sẽ được update

Tuy nhiên, điều trên chỉ áp dụng nếu mô hình cha cũng đang được cập nhật. Ví dụ: nếu bạn muốn tạo một member có tên Joe và muốn cập nhật các post cùng lúc, điều đó sẽ gây ra lỗi ActiveRecord :: RecordNotFound.

Để destroy bản ghi con thì ta cũng làm tương tự với quan hệ 1-1

2.3. Các option thường được sử dụng

  • :allow_destroy Cho phép xóa bản ghi con, truyền vào _destroy một giá trị true sẽ thực hiện việc xóa các bản ghi con. Bản ghi chỉ được xóa khi bản ghi cha đã lưu thành công.
  • :reject_if Cho phép chỉ định một Proc hoặc một Symbol trỏ đến method kiểm tra điều kiện, cả hai có giá trị trả về là true/false. Khi false, :reject_if không được gọi, nested attributes sẽ được tạo với đầy đủ giá trị cho từng trường ngoại trừ _destroy, khi điều kiện trả về false thì trường _destroy sẽ được gán giá trị true để hủy đi bản ghi đó.
  • :limit (1-n) Cho phép chỉ định số lượng bản ghi con tối đa có thể tạo được trong bản ghi cha. Nếu số lượng bản ghi con vượt quá giới hạn limit thì raised exception NestedAttributes :: TooManyRecords
  • :update_only (1-1) Nếu muốn update bản ghi con mà không cần thêm :id

3. Tham khảo

To be continued…

https://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

Bài viết đầu tiên còn nhiều thiếu sót rất mong các bạn thông cảm, bài sau mình sẽ hướng dẫn các bạn về cách dùng Nested Attributesthực tế . Cảm ơn các bạn đã scroll chuột tới đây ? !

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo