Skip to content

Commit 504616e

Browse files
committed
Merge branch 'master' of github.com:JsonApiClient/json_api_client
2 parents df414ec + b4e7dde commit 504616e

File tree

3 files changed

+41
-0
lines changed

3 files changed

+41
-0
lines changed

lib/json_api_client/errors.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ def track_json_api_errors(msg)
3232
class ClientError < ApiError
3333
end
3434

35+
class ResourceImmutableError < StandardError
36+
def initialize(msg = 'Resource immutable')
37+
super msg
38+
end
39+
end
40+
3541
class AccessDenied < ClientError
3642
end
3743

lib/json_api_client/resource.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ class Resource
4040
instance_accessor: false
4141
class_attribute :add_defaults_to_changes,
4242
instance_writer: false
43+
44+
class_attribute :_immutable,
45+
instance_writer: false,
46+
default: false
47+
4348
self.primary_key = :id
4449
self.parser = Parsers::Parser
4550
self.paginator = Paginating::Paginator
@@ -94,6 +99,18 @@ def type
9499
table_name
95100
end
96101

102+
# Indicates whether this resource is mutable or immutable;
103+
# by default, all resources are mutable.
104+
#
105+
# @return [Boolean]
106+
def immutable(flag = true)
107+
self._immutable = flag
108+
end
109+
110+
def inherited(subclass)
111+
subclass._immutable = false
112+
end
113+
97114
# Specifies the relative path that should be used for this resource;
98115
# by default, this is inferred from the resource class name.
99116
#
@@ -215,6 +232,11 @@ def route_formatter
215232
# @option [Symbol] :on One of [:collection or :member] to decide whether it's a collect or member method
216233
# @option [Symbol] :request_method The request method (:get, :post, etc)
217234
def custom_endpoint(name, options = {})
235+
if _immutable
236+
request_method = options.fetch(:request_method, :get).to_sym
237+
raise JsonApiClient::Errors::ResourceImmutableError if request_method != :get
238+
end
239+
218240
if :collection == options.delete(:on)
219241
collection_endpoint(name, options)
220242
else
@@ -440,6 +462,7 @@ def valid?(context = nil)
440462
# @return [Boolean] Whether or not the save succeeded
441463
def save
442464
return false unless valid?
465+
raise JsonApiClient::Errors::ResourceImmutableError if _immutable
443466

444467
self.last_result_set = if persisted?
445468
self.class.requestor.update(self)
@@ -470,6 +493,8 @@ def save
470493
#
471494
# @return [Boolean] Whether or not the destroy succeeded
472495
def destroy
496+
raise JsonApiClient::Errors::ResourceImmutableError if _immutable
497+
473498
self.last_result_set = self.class.requestor.destroy(self)
474499
if last_result_set.has_errors?
475500
fill_errors

test/unit/resource_test.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,14 @@ def test_default_params_overrideable
9595
assert_equal(article.type, 'Story')
9696
end
9797

98+
def test_immutable
99+
Article.immutable(true)
100+
article = Article.new(type: 'Story')
101+
assert_raises JsonApiClient::Errors::ResourceImmutableError do
102+
article.save
103+
end
104+
ensure
105+
Article.immutable(false)
106+
end
107+
98108
end

0 commit comments

Comments
 (0)