Rails Active Record Thuộc tính lồng nhau

Tram Ho

Nested attributes

Nested attributes cho phép bạn lưu các thuộc tính của các object con bằng parent object. Mặc định thì nested attribute sẽ bị disable, bạn có thể enable nó để sử dụng bằng class method accepts_nested_attributes_for. Khi bạn enable nested attribute thì một attribute writer sẽ được định nghĩa trong model.
Sau khi attribute writer được định nghĩa, theo ví dụ dưới đây thì hai method mới sẽ được thêm vào model author_attributes=(attributes)pages_attributes=(attributes)

Chú ý: :autosave option sẽ được tự động thêm vào các association mà được sử dụng accepts_nested_attributes_for

One-to-one

Cùng xem xét ví dụ: model Member có một Avatar

Sử dụng nested attributes cho one-to-one association cho phép bạn tạo mới một Member với Avatar chỉ với một lần create:

Nó cho phép bạn update avatar thông qua member:

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

Mặc định, bạn chỉ có thể set và update các thuộc tính trong model. Nếu bạn muốn destroy các thuộc tính association, bạn phải enable nó bằng :allow_destroy option:

Khi đó, khi bạn thêm _destroy key với giá trị true vào attributes hash thì associated model sẽ bị xóa:

Chú ý: Model sẽ không bị xóa trừ khi bạn lưu model cha (member.save).

One-to-many

Xét ví dụ: Một Member có nhiều bài posts:

Bây giờ bạn có thể set hoặc update associated posts bằng cách thêm key :posts_attributes với giá trị là mảng các hash là các thuộc tính của post:

Bạn cũng có thể thêm :reject_if để loại bỏ các record nếu nó không thỏa mãn điều kiện của nó. Như vậy ví dụ ở trên có thể viết lại như sau:

Bên cạnh đó bạn cũng có thể truyền vào :reject_if một symbol để gọi đến một method:

Nếu id truyền vào mà trùng với một record đã tồn tại thì nó sẽ được ghi đè và chỉnh sửa lại:

Tuy nhiên, trường hợp trên chỉ chạy nếu như parent model đã được tạo. Ví dụ, nếu bạn muốn tạo một member với tên “joe” và update posts ngay cùng thời điểm nó sẽ raise lỗi ActiveRecord::RecordNotFound

Mặc định thì các associated record được bảo vệ để không bị xóa. Nếu bạn muốn xóa một associated record, bạn phải enable nó trước bằng cách sử dụng option allow_destroy: true:

Các thuộc tính cho một associated cũng có thể được viết dưới dạng một chuỗi hash thay vì một mảng hash.

có tác dụng tương tự như:

Validating the presence of a parent model

Bạn có thể sử dụng validates_presence_of method và :inverse_of key để validate một bản ghi con được liên kết với một bản ghi cha.

Chú ý rằng, nếu bạn không chỉ định cho :inverse_of option thì Active Record sẽ tự động đoán inverse association.
Đối với one-to-one nested associations, nếu bạn tạo mới (in-memory) một object con trước khi gán nó, thì module đó sẽ không bị ghi đè:

Tài liệu tham khảo

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo