Skip to content

adding create!, update_attributes!, update! methods #389

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Unreleased

- [#389](https://github.com/JsonApiClient/json_api_client/pull/389)-adding create!, update_attributes!, update! methods

## 1.19.0
- [#382](https://github.com/JsonApiClient/json_api_client/pull/382) - Add extra error classes to hande server errors.

Expand Down
11 changes: 11 additions & 0 deletions lib/json_api_client/errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,5 +103,16 @@ def initialize(code, uri)
super nil, msg
end
end

class RecordNotSaved < ServerError
attr_reader :record

def initialize(message = nil, record = nil)
@record = record
end
def message
"Record not saved"
end
end
end
end
15 changes: 15 additions & 0 deletions lib/json_api_client/resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,12 @@ def create(attributes = {})
end
end

def create!(attributes = {})
new(attributes).tap do |resource|
raise(Errors::RecordNotSaved.new("Failed to save the record", resource)) unless resource.save
end
end

# Within the given block, add these headers to all requests made by
# the resource class
#
Expand Down Expand Up @@ -376,6 +382,11 @@ def update_attributes(attrs = {})
save
end

def update_attributes!(attrs = {})
self.attributes = attrs
save ? true : raise(Errors::RecordNotSaved.new("Failed to update the record", self))
end

# Alias to update_attributes
#
# @param attrs [Hash] Attributes to update
Expand All @@ -384,6 +395,10 @@ def update(attrs = {})
update_attributes(attrs)
end

def update!(attrs = {})
update_attributes!(attrs)
end

# Mark the record as persisted
def mark_as_persisted!
@persisted = true
Expand Down
75 changes: 75 additions & 0 deletions test/unit/creation_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,23 @@ def test_can_create_with_class_method
assert_equal "Rails is Omakase", article.title
end

def test_failed_create!
stub_request(:post, "http://example.com/users")
.to_return(headers: {content_type: "application/vnd.api+json"}, body: {
errors: [
{
status: "400",
title: "Error"
}
]
}.to_json)

exception = assert_raises JsonApiClient::Errors::RecordNotSaved do
User.create!(name: 'Hans')
end
assert_equal "Record not saved", exception.message
end

def test_changed_attributes_empty_after_create_with_class_method
stub_simple_creation
article = Article.create({
Expand Down Expand Up @@ -206,7 +223,65 @@ def test_can_create_with_new_record_with_relationships_and_save
assert article.persisted?
assert_equal article.comments.length, 1
assert_equal "1", article.id
end

def test_can_create_with_new_record_with_associated_relationships_and_save
stub_request(:post, "http://example.com/articles")
.with(headers: {content_type: "application/vnd.api+json", accept: "application/vnd.api+json"}, body: {
data: {
type: "articles",
relationships: {
author: {
data: {
id: 1,
type: "authors"
}
}
},
attributes: {
title: "Rails is Omakase"
}
}
}.to_json)
.to_return(headers: {content_type: "application/vnd.api+json"}, body: {
data: {
type: "articles",
id: "1",
attributes: {
title: "Rails is Omakase"
},
relationships: {
author: {
data: [
{
id: "1",
type: "comments"
}
]
}
}
},
included: [
{
id: "1",
type: "authors",
}
]
}.to_json)

author_hash = {
author: {
data: {
id: 1,
type: 'authors'
}
}
}
article = Article.new({title: "Rails is Omakase", "relationships" => author_hash})

assert article.save
assert article.persisted?
assert_equal "1", article.id
end

def test_correct_create_with_nil_attribute_value
Expand Down
30 changes: 30 additions & 0 deletions test/unit/updating_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,36 @@ def stub_simple_fetch
}.to_json)
end

def test_failed_update!
stub_simple_fetch
articles = Article.find(1)
article = articles.first

stub_request(:patch, "http://example.com/articles/1")
.with(headers: {content_type: "application/vnd.api+json", accept: "application/vnd.api+json"}, body: {
data: {
id: "1",
type: "articles",
attributes: {
title: "Modified title",
}
}
}.to_json)
.to_return(headers: {content_type: "application/vnd.api+json"}, body: {
errors: [
{
status: "400",
title: "Error"
}
]
}.to_json)

exception = assert_raises JsonApiClient::Errors::RecordNotSaved do
article.update!(title: 'Modified title')
end
assert_equal "Record not saved", exception.message
end

def test_can_update_found_record
stub_simple_fetch
articles = Article.find(1)
Expand Down