Rails Active Record Nested Attributes

Tram Ho

Nested attributes

Nested attributes allows you to store the properties of child objects using a parent object. By default, the nested attribute will be disabled, you can enable it for use with the class method accepts_nested_attributes_for . When you enable the nested attribute an attribute writer will be defined in the model. After the attribute writer been defined, in the following example, two new methods will be added to model author_attributes=(attributes) and pages_attributes=(attributes)

Note :autosave option will be automatically added to associations that are accepts_nested_attributes_for

One-to-one

Let’s look at the example: Member model has an Avatar

Using nested attributes for one-to-one association allows you to create a new Member with Avatar with just one create:

It allows you to update your avatar through members:

If you want to update your avatar without providing its id, you must add the option :update_only :

By default, you can only set and update properties in the model. If you want to destroy association properties, you must enable it with :allow_destroy option:

Then, when you add a _destroy key with a true value to the attributes hash, the associated model is deleted:

Note: The model will not be deleted unless you save the parent model (member.save).

One-to-many

Consider the example: A Member has many posts:

You can now set or update associated posts by adding the key :posts_attributes whose value is the array of hashes as post attributes:

You can also add :reject_if to reject records if it doesn’t meet its condition. So the above example can be rewritten as follows:

You can also pass :reject_if a symbol to call a method:

If the passed id matches an existing record, it will be overwritten and edited:

However, this will only work if the parent model has been created. For example, if you want to create a member with the name “joe” and update posts at the same time it will raise the error ActiveRecord::RecordNotFound

By default, associated records are protected from being deleted. If you want to remove a associated record, you must enable it first using the allow_destroy: true option:

Properties for a associated can also be written as a string of hash instead of a hash array.

has the same effect as:

Validating the presence of a parent model

You can use the validates_presence_of method and :inverse_of key to validate a child record associated with a parent record.

Note that, if you don’t specify the :inverse_of option, the Active Record will automatically guess the inverse association. For one-to-one nested associations, if you create (in-memory) a sub-object before assigning it, that module will not be overwritten:

References

Share the news now

Source : Viblo