
Security News
The Changelog Podcast: Practical Steps to Stay Safe on npm
Learn the essential steps every developer should take to stay secure on npm and reduce exposure to supply chain attacks.
activerecord-jsonapi_update
Advanced tools
Update ActiveRecord instances and their associations, consistent with JSON API specification.
The JSON API specification says the following:
If a relationship is provided in the relationships member of a resource object in a PATCH request, its value ... will be replaced with the value specified in this member.
The example provided is particularly clear:
... the following PATCH request performs a complete replacement of the tags for an article:
PATCH /articles/1 HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json
{
"data": {
"type": "articles",
"id": "1",
"relationships": {
"tags": {
"data": [
{ "type": "tags", "id": "2" },
{ "type": "tags", "id": "3" }
]
}
}
}
}
Which, depending on your deserialization solution, would likely be interpreted as:
article_attributes = {
id: '1',
tag_ids: ['2', '3']
}
@article.update(article_attributes)
@article.reload.tag_ids # => [2, 3]
Which would work correctly (any tags that were previously associated with the article that were not mentioned in the new tag_ids would be destroyed).
However consider when your model accepts nested attributes, and you then want to specify a new tag as well as keep an old one:
PATCH /articles/1 HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json
{
"data": {
"type": "articles",
"id": "1",
"relationships": {
"tags": {
"data": [
{ "type": "tags", "id": "2" },
{ "type": "tags", "id": "clientid1" } // New tag
]
}
},
"included": [
{
"type": "tag",
"id": "clientid1",
"attributes": {
"name": "New Tag"
}
}
]
}
}
This will likely get processed as (assuming you're removing client ids):
article_attributes = {
id: '1',
tags_attributes: {
0: {
id: '2'
},
1: {
name: 'New Tag'
},
}
}
@article.update(article_attributes) # The new tag is given id 4
@article.reload.tag_ids # => [2, 3, 4]
@article.update(article_attributes) correctly creates the new tag and keeps the one that should be kept (id: 2), but it doesn't get rid of the old one (id: 3).
That's when you need activerecord-jsonapi_update:
@article.jsonapi_update(article_attributes) # The new tag is given id 4
@article.reload.tag_ids # => [2, 4]
Add this line to your application's Gemfile:
gem 'activerecord-jsonapi_update'
And then execute:
$ bundle
Or install it yourself as:
$ gem install activerecord-jsonapi_update
activerecord-jsonapi_update provides 3 new methods on ActiveRecord instances:
jsonapi_update instead of updatejsonapi_update! instead of update!assign_jsonapi_attributes instead of assign_attributesEach has the same method signature (arguments) as the ActiveRecord method it replaces.
For example:
def update
@article = Article.find(params[:id])
if @article.jsonapi_update(allowed_params)
render json: @article, status: :success
end
end
jsonapi_update does not side-step any of the normal ActiveRecord functionality (and limits itself to pre-processing the attributes it's provided), so in order to allow destroying nested attributes you must still explicitly permit it in the accepts_nested_attributes declaration.
class Article < ActiveRecord::Base
accepts_nested_attributes_for :tags, allow_destroy: true
end
You will also have configure strong parameters correctly in your controller to permit the associated resource attributes:
def allowed_params
params.from_jsonapi.permit(:id, tags: [:id, :name])
end
To accommodate this, nested hashes or arrays with the _attributes suffix are processed as follows:
*_attributes hash or array will be destroyed
(which is not how the normal #update method functions.)The jsonapi_update method intends to be as light-weight as possible, but it does carry with it a slight overhead that depends on the size and complexity of the hash of values you're using to update your models.
It also only has any effect when:
So only use jsonapi_update when you actually want to support the replacement of the entire collection of associated resources on a particular endpoint and you have configured your controller and models to allow it.
Please see the relevant section of the JSON API specification for a full discussion of supporting or rejecting updating associated resources.
FAQs
Unknown package
We found that activerecord-jsonapi_update demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Learn the essential steps every developer should take to stay secure on npm and reduce exposure to supply chain attacks.

Security News
Experts push back on new claims about AI-driven ransomware, warning that hype and sponsored research are distorting how the threat is understood.

Security News
Ruby's creator Matz assumes control of RubyGems and Bundler repositories while former maintainers agree to step back and transfer all rights to end the dispute.