naranya_ecm-sdk 0.0.42 → 0.0.43

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/.rspec +3 -0
  4. data/Gemfile +1 -2
  5. data/lib/aasm/persistence/rest_persistence.rb +11 -6
  6. data/lib/naranya_ecm-sdk.rb +4 -65
  7. data/lib/naranya_ecm-sdk/version.rb +1 -1
  8. data/lib/naranya_ecm/models/media_resource.rb +1 -1
  9. data/lib/naranya_ecm/models/notification.rb +2 -2
  10. data/lib/naranya_ecm/rest/errors.rb +16 -3
  11. data/lib/naranya_ecm/rest/finder_methods.rb +4 -4
  12. data/lib/naranya_ecm/rest/model.rb +87 -19
  13. data/lib/naranya_ecm/rest/persistence.rb +234 -46
  14. data/lib/naranya_ecm/rest/relation.rb +15 -5
  15. data/lib/naranya_ecm/search/results.rb +19 -17
  16. data/lib/ncontent-sdk-testing.rb +13 -0
  17. data/lib/ncontent-sdk.rb +85 -0
  18. data/lib/ncontent/sdk/config.rb +75 -0
  19. data/lib/ncontent/sdk/faraday_middleware.rb +4 -0
  20. data/lib/ncontent/sdk/faraday_middleware/required_response_format.rb +14 -0
  21. data/lib/ncontent/sdk/faraday_middleware/response_parser.rb +35 -0
  22. data/lib/ncontent/sdk/faraday_middleware/rest_api_call_benchmark.rb +49 -0
  23. data/lib/ncontent/sdk/railtie.rb +59 -0
  24. data/lib/ncontent/sdk/rest_client.rb +131 -0
  25. data/lib/ncontent/sdk/testing/server_mock.rb +316 -0
  26. data/naranya_ecm-sdk.gemspec +24 -10
  27. metadata +85 -68
  28. data/lib/naranya_ecm/rest/client.rb +0 -92
  29. data/spec/models/category_spec.rb +0 -16
  30. data/spec/models/content_spec.rb +0 -20
  31. data/spec/models/content_version_spec.rb +0 -7
  32. data/spec/models/download_authorization.rb +0 -7
  33. data/spec/models/media_spec.rb +0 -7
  34. data/spec/models/module_spec.rb +0 -18
  35. data/spec/spec_helper.rb +0 -47
  36. data/spec/support/naranya_ecms_shared_specs.rb +0 -21
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: edcb5360a556fa04739d34bda3fd6ae7e3f0a696
4
- data.tar.gz: 6e2f6e3fe4f775b8e0df4a4c76c18299a5249740
3
+ metadata.gz: 183c574009558b2788b71cce8899e52e9a948344
4
+ data.tar.gz: d1ffcd41db7e78e43251c7714c7e7ec686223b15
5
5
  SHA512:
6
- metadata.gz: 743f9b659c78a0b6c972092c032d81a0cd20e337ac2db8091ab4fbf57da82f731cc1f3932c27d279e1c4dd7c3e10e5d9790a841b68587523431c68b3342b884b
7
- data.tar.gz: 8f1ef6a70618d0e6857ed2bbfe648c79cbece07e36268ab2a2eab8cfc87472e394e4ea0c3852be46ce92bed1f7f20ac028e7cf633644526fbb9f32fc26eb63b9
6
+ metadata.gz: c010113401ef577a7b24a41e50614c4d98c77c91eba374f421279e224aa2529fac258423b9e2d19f00451d7950a7dad90f8a7e209f2dee6ddc230a6a60dae6e7
7
+ data.tar.gz: 5fd603773082dbcd115d97e36b1ab9f68649c3ae3bd81b1e717ea43b32f87389fdda26188de350378337c133ebd2511fea3560c9cf6e49de44b4965521f90d70
data/.gitignore CHANGED
@@ -10,4 +10,5 @@ spec/dummy/.sass-cache
10
10
  Gemfile.lock
11
11
  /naranya_ecm.yml
12
12
  /.irb*
13
- /naranya_ecm-sdk-*.gem
13
+ /naranya_ecm-sdk-*.gem
14
+ /*.env
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format documentation
3
+ --require spec_helper
data/Gemfile CHANGED
@@ -6,5 +6,4 @@ gemspec
6
6
  gem 'redis-activesupport'
7
7
  gem 'pry', require: 'pry'
8
8
  gem 'byebug'
9
-
10
- #gem 'activeresource', path: '../other/activeresource'
9
+ gem "patron"
@@ -32,7 +32,7 @@ module AASM
32
32
  base.send(:include, AASM::Persistence::RestPersistence::InstanceMethods)
33
33
 
34
34
  base.before_validation(:aasm_ensure_initial_state, :on => :create)
35
-
35
+
36
36
  # ensure initial aasm state even when validations are skipped
37
37
  base.before_create(:aasm_ensure_initial_state)
38
38
 
@@ -108,18 +108,23 @@ module AASM
108
108
  # end
109
109
 
110
110
  private
111
-
111
+
112
112
  def aasm_ensure_initial_state
113
113
  send("#{self.class.aasm_column}=", aasm.enter_initial_state.to_s) if send(self.class.aasm_column).blank?
114
114
  end
115
115
 
116
116
  def aasm_fire_event(name, options, *args, &block)
117
117
  local_success = super
118
-
118
+
119
119
  if local_success
120
120
  data = { name: name, target_type: self.class.name.demodulize, target_id: self.id }
121
- response = ::NaranyaEcm::Rest::Client.post "/events.json", body: { state_event: data }
122
- remote_success = response.success?
121
+
122
+ response = NContent::SDK::RESTClient.post "/events.json" do |req|
123
+ req.headers[:content_type] = 'application/json'
124
+ req.body = ActiveSupport::JSON.encode(state_event: data)
125
+ end
126
+
127
+ remote_success = response.status < 400
123
128
  unless remote_success
124
129
  end
125
130
  end
@@ -131,4 +136,4 @@ module AASM
131
136
 
132
137
  end
133
138
  end
134
- end
139
+ end
@@ -1,13 +1,14 @@
1
1
  require 'naranya_ecm-sdk/version'
2
2
 
3
3
  require 'active_support/time'
4
- require 'active_support/configurable'
5
4
  require 'active_support/dependencies/autoload'
6
5
  require 'active_support/core_ext/hash/indifferent_access.rb'
7
6
  require 'yaml'
8
7
 
9
8
  require 'fog/aws/storage' unless defined?(::Fog::AWS::Storage)
10
9
 
10
+ require 'ncontent-sdk'
11
+
11
12
  module NaranyaEcm
12
13
 
13
14
  extend ActiveSupport::Autoload
@@ -22,7 +23,6 @@ module NaranyaEcm
22
23
  # that connects the NaranyaEcm models with the Naranya CaaS REST services.
23
24
  module Rest
24
25
  extend ActiveSupport::Autoload
25
- autoload :Client
26
26
  autoload :Errors
27
27
  autoload :Persistence
28
28
  autoload :Associations
@@ -65,68 +65,7 @@ module NaranyaEcm
65
65
  autoload :Results
66
66
  end
67
67
 
68
- include ActiveSupport::Configurable
69
-
70
- DEFAULT_CONFIG = {
71
- site: "http://ecm.naranya.net:5000",
72
- client_notify_url: "http://www.example.com/naranya_ecm/notifications",
73
- notification_processing_modules: []
74
- }.freeze
75
-
76
- class << self
77
-
78
- def storage
79
- @storage ||= Fog::Storage.new options[:storage].except(:root_directory)
80
- end
81
-
82
- def root_directory
83
- @root_directory ||= storage.directories.get(options[:storage][:root_directory])
84
- end
85
-
86
- def setup; yield config; end
87
- def document_module; NaranyaEcm::Rest::Model; end
88
- def timestamp_module; NaranyaEcm::Behaviors::Timestampable; end
89
-
90
- def options
91
- auto_conf unless config.present?
92
- config
93
- end
94
-
95
- def cache
96
- auto_conf unless config.present?
97
- @cache ||= ActiveSupport::Cache.lookup_store *options[:cache]
98
- end
99
-
100
- def logger
101
- auto_conf unless config.present?
102
- @logger ||= Logger.new($stdout)
103
- end
104
-
105
- def load_config_from_yml(yml_path, env="production")
106
- raise "YAML file doesn't extst" unless File.exist?(yml_path)
107
- yml_config = DEFAULT_CONFIG.merge(YAML::load(ERB.new(File.read(yml_path)).result)[env])
108
- .with_indifferent_access
109
- setup { |config| yml_config.each { |key, val| config.send "#{key}=".to_sym, val } }
110
- end
111
-
112
- protected
113
-
114
- def auto_conf
115
- # Cargar configuracion dentro del folder de config en Rails:
116
- if defined?(Rails)
117
- yml_path = File.join(Rails.root, 'config', 'naranya_ecm.yml')
118
- load_config_from_yml(yml_path, Rails.env)
119
-
120
- # Use the Rails cache:
121
- @cache = Rails.cache
122
-
123
- # Use the Rails logger:
124
- @logger = Rails.logger
125
- elsif File.exists?('./naranya_ecm.yml')
126
- load_config_from_yml('./naranya_ecm.yml')
127
- end
128
- end
129
-
130
- end
68
+ def self.document_module; NaranyaEcm::Rest::Model; end
69
+ def self.timestamp_module; NaranyaEcm::Behaviors::Timestampable; end
131
70
 
132
71
  end
@@ -1,3 +1,3 @@
1
1
  module NaranyaEcm
2
- VERSION = "0.0.42"
2
+ VERSION = "0.0.43"
3
3
  end
@@ -95,7 +95,7 @@ module NaranyaEcm
95
95
  # Returns the storage root directory, depending of the storage engine:
96
96
  # - Amazon AWS S3: A Fog::Storage::AWS::Directory object
97
97
  def self.root_directory
98
- NaranyaEcm.root_directory
98
+ NContent::SDK.root_directory
99
99
  end
100
100
 
101
101
  def move_downloadable_to(path, force_move=false)
@@ -16,8 +16,8 @@ module NaranyaEcm
16
16
  alias_method_chain :initialize, :attributes_hash
17
17
 
18
18
  def process
19
- NaranyaEcm.logger.debug "NaranyaEcm::Notification: #{self.attributes}"
20
- NaranyaEcm.logger.debug "NaranyaEcm::Notification: No processing implemented."
19
+ NContent::SDK.logger.debug "NaranyaEcm::Notification: #{self.attributes}"
20
+ NContent::SDK.logger.debug "NaranyaEcm::Notification: No processing implemented."
21
21
  end
22
22
 
23
23
  def method_missing(method, *args, &block)
@@ -14,14 +14,14 @@ module NaranyaEcm::Rest
14
14
  ##
15
15
  # Captura un response y genera + avienta una excepción.
16
16
  def self.raise_by_failed_response(response, message = "")
17
- klass = case response.code
17
+ klass = case response.status
18
18
  when 401 then AuthorizationRequired
19
19
  when 403 then Forbidden
20
20
  when 404 then ResourceNotFound
21
21
  when 422 then UnprocessableEntity
22
22
  else RemoteFailed
23
23
  end
24
- raise klass.new response, "Server responded with code #{response.code}. Message: #{message}"
24
+ raise klass.new response, "Server responded with code #{response.status}. Message: #{message}"
25
25
  end
26
26
 
27
27
  end
@@ -73,6 +73,19 @@ module NaranyaEcm::Rest
73
73
  end
74
74
 
75
75
  class AuthorizationRequired < RestError
76
+
77
+ def self.parse_www_authenticate_header(response)
78
+ Hash[response.headers['WWW-Authenticate'].scan(/(\w+)="([^"]+)"/)] \
79
+ if response.headers['WWW-Authenticate']
80
+ end
81
+
82
+ delegate :parse_www_authenticate_header, to: :class
83
+
84
+ def initialize(given_response, msg = "")
85
+ data = parse_www_authenticate_header given_response
86
+ super given_response,
87
+ "#{data['error_description']} (HTTP status #{given_response.status})"
88
+ end
76
89
  end
77
90
 
78
91
  class Forbidden < RestError
@@ -84,4 +97,4 @@ module NaranyaEcm::Rest
84
97
  class RemoteFailed < RestError
85
98
  end
86
99
 
87
- end
100
+ end
@@ -1,5 +1,4 @@
1
1
  require 'naranya_ecm/rest/errors'
2
- require 'naranya_ecm/rest/client'
3
2
 
4
3
  module NaranyaEcm::Rest
5
4
 
@@ -19,12 +18,13 @@ module NaranyaEcm::Rest
19
18
  protected
20
19
 
21
20
  def find_one(id)
22
- self.load fetch_one(id)
21
+ found_resource = self.load fetch_one(id)
22
+ found_resource.instance_variable_set("@new_resource", false)
23
+ found_resource
23
24
  end
24
25
 
25
26
  def fetch_one(id)
26
- format = NaranyaEcm.options[:format] || 'json'
27
- Client.get("#{path}/#{id}.#{format}").to_hash
27
+ NContent::SDK::RESTClient.get("#{path}/#{id}.json").body
28
28
  end
29
29
  end
30
30
  end
@@ -50,7 +50,7 @@ module NaranyaEcm::Rest
50
50
  end
51
51
 
52
52
  extend ActiveSupport::Concern
53
-
53
+
54
54
  included do
55
55
 
56
56
  include ActiveModel::Model
@@ -66,14 +66,16 @@ module NaranyaEcm::Rest
66
66
  include NaranyaEcm::Rest::Persistence
67
67
 
68
68
  extend NaranyaEcm::Rest::FinderMethods
69
-
69
+
70
70
  alias_method_chain :initialize, :defaults
71
71
 
72
- if NaranyaEcm.options[:extra_attributes] && (extra_fields = NaranyaEcm.options[:extra_attributes][self.name.demodulize.underscore])
72
+ if NContent::SDK.config.extra_attributes.present? and
73
+ extra_fields = NContent::SDK.config.extra_attributes[self.name.demodulize.underscore]
74
+
73
75
  extra_fields.each do |name, type|
74
-
76
+
75
77
  field_options = {}
76
-
78
+
77
79
  field_options[:type] = case type
78
80
  when 'boolean'
79
81
  NaranyaEcm::Rest::Model::BOOLEAN
@@ -88,12 +90,14 @@ module NaranyaEcm::Rest
88
90
  end
89
91
 
90
92
  def initialize_with_defaults(*args)
93
+ init_internals
94
+
91
95
  initialize_without_defaults(*args)
92
96
  # inicializar con los valores default los campos que esten nulos y tengan un default definido:
93
97
  self.class.fields.values
94
98
  .select { |f| instance_variable_get("@#{f[:name]}".to_sym).nil? && f[:default] }
95
99
  .each { |f| instance_variable_set("@#{f[:name]}".to_sym, f[:default].call) }
96
-
100
+
97
101
  end
98
102
 
99
103
  def method_missing(method, *args, &block)
@@ -108,10 +112,42 @@ module NaranyaEcm::Rest
108
112
  end
109
113
 
110
114
  def attributes
111
- HashWithIndifferentAccess[
112
- self.class.fields.values
113
- .map { |attr_data| [attr_data[:name], self.send(attr_data[:name].to_sym)] }
114
- ]
115
+ self.class.fields.values.inject('id' => self.id) do |hsh, attr_data|
116
+ hsh[attr_data[:name].to_s] = self.public_send attr_data[:name]
117
+ hsh
118
+ end.with_indifferent_access
119
+ end
120
+
121
+ # Returns an <tt>#inspect</tt>-like string for the value of the
122
+ # attribute +attr_name+. String attributes are truncated upto 50
123
+ # characters, Date and Time attributes are returned in the
124
+ # <tt>:db</tt> format, Array attributes are truncated upto 10 values.
125
+ # Other attributes return the value of <tt>#inspect</tt> without
126
+ # modification.
127
+ #
128
+ # person = Person.create!(name: 'David Heinemeier Hansson ' * 3)
129
+ #
130
+ # person.attribute_for_inspect(:name)
131
+ # # => "\"David Heinemeier Hansson David Heinemeier Hansson ...\""
132
+ #
133
+ # person.attribute_for_inspect(:created_at)
134
+ # # => "\"2012-10-22 00:15:07\""
135
+ #
136
+ # person.attribute_for_inspect(:tag_ids)
137
+ # # => "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...]"
138
+ def attribute_for_inspect(attr_name)
139
+ value = self.public_send(attr_name)
140
+
141
+ if value.is_a?(String) && value.length > 50
142
+ "#{value[0, 50]}...".inspect
143
+ elsif value.is_a?(Date) || value.is_a?(Time)
144
+ %("#{value.to_s(:db)}")
145
+ elsif value.is_a?(Array) && value.size > 10
146
+ inspected = value.first(10).inspect
147
+ %(#{inspected[0...-1]}, ...])
148
+ else
149
+ value.inspect
150
+ end
115
151
  end
116
152
 
117
153
  def associations
@@ -131,12 +167,19 @@ module NaranyaEcm::Rest
131
167
  "#{self.class.path}/#{self.id}"
132
168
  end
133
169
 
134
- protected
170
+ # Returns the contents of the record as a nicely formatted string.
171
+ def inspect
172
+ # We check defined?(@attributes) not to issue warnings if the object is
173
+ # allocated but not initialized.
174
+ inspection = (['id'] + self.class.fields.keys.sort).map { |name|
175
+ value = attribute_for_inspect(name)
176
+ "#{name}: #{value}" unless value == 'nil'
177
+ }.compact.join(", ")
135
178
 
136
- def off_band_changes
137
- @off_band_changes ||= {}.with_indifferent_access
138
- end
179
+ inspection = "not initialized" if inspection.blank?
139
180
 
181
+ "#<#{self.class} #{inspection}>"
182
+ end
140
183
 
141
184
  module ClassMethods
142
185
 
@@ -157,14 +200,14 @@ module NaranyaEcm::Rest
157
200
  end
158
201
 
159
202
  def field(name, options = {})
160
-
203
+
161
204
  if options[:localize]
162
205
  lookup_alias_name = name
163
206
  name = "#{name}_translations".to_sym
164
207
  end
165
208
 
166
209
  fields[name] = {name: name}.merge(options).with_indifferent_access
167
-
210
+
168
211
  attr_accessor name
169
212
  define_attribute_method name
170
213
 
@@ -201,7 +244,7 @@ module NaranyaEcm::Rest
201
244
  end
202
245
 
203
246
  def where(given_conditions={})
204
- Relation.new self, given_conditions.with_indifferent_access
247
+ Relation.new self, given_conditions.with_indifferent_access
205
248
  end
206
249
 
207
250
  delegate :first, :last, to: :all
@@ -209,7 +252,32 @@ module NaranyaEcm::Rest
209
252
  def all
210
253
  where()
211
254
  end
212
-
255
+
256
+ end
257
+
258
+ # Returns +true+ if the resource is read only.
259
+ def readonly?
260
+ @readonly
213
261
  end
262
+
263
+ # Marks this record as read only.
264
+ def readonly!
265
+ @readonly = true
266
+ end
267
+
268
+ protected
269
+
270
+ def off_band_changes
271
+ @off_band_changes ||= {}.with_indifferent_access
272
+ end
273
+
274
+ private
275
+
276
+ def init_internals
277
+ @readonly = false
278
+ @destroyed = false
279
+ @new_resource = true
280
+ end
281
+
214
282
  end
215
- end
283
+ end
@@ -1,9 +1,67 @@
1
1
  module NaranyaEcm::Rest
2
2
 
3
3
  module Persistence
4
-
5
4
  extend ActiveSupport::Concern
6
5
 
6
+ class ReadOnlyResource < StandardError
7
+ end
8
+
9
+ class ResourceNotSaved < StandardError
10
+ end
11
+
12
+ class ResourceNotDestroyed < StandardError
13
+ end
14
+
15
+ module ClassMethods
16
+
17
+ # Updates an object (or multiple objects) and saves it to the server, if
18
+ # validations pass.
19
+ #
20
+ # The resulting object is returned whether the object was saved
21
+ # successfully to the server or not.
22
+ #
23
+ # ==== Parameters
24
+ #
25
+ # * +id+ - This should be the id or an array of ids to be updated.
26
+ # * +attributes+ - This should be a hash of attributes or an array of hashes.
27
+ #
28
+ # ==== Examples
29
+ #
30
+ # # Updates one resource
31
+ # Person.update(15, user_name: 'Samuel', group: 'expert')
32
+ #
33
+ # # Updates multiple resources
34
+ # people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy" } }
35
+ # Person.update(people.keys, people.values)
36
+ def update(id, attributes)
37
+ if id.is_a?(Array)
38
+ id.map.with_index { |one_id, idx| update(one_id, attributes[idx]) }
39
+ else
40
+ object = find(id)
41
+ object.update(attributes)
42
+ object
43
+ end
44
+ end
45
+
46
+ def create(attributes={})
47
+ object_to_create = self.new attributes
48
+ object_to_create.save
49
+ object_to_create
50
+ end
51
+
52
+ def create!(attributes={})
53
+ created_object = create(attributes)
54
+ raise "ValidationError" unless created_object.persisted?
55
+ created_object
56
+ end
57
+
58
+ def delete(id, options={})
59
+ response = NContent::SDK::RESTClient.delete("#{self.path}/#{id}.json")
60
+ true
61
+ end
62
+
63
+ end
64
+
7
65
  included do
8
66
  define_model_callbacks :validation, :create, :update, :save, :destroy
9
67
  end
@@ -13,18 +71,98 @@ module NaranyaEcm::Rest
13
71
  self.update
14
72
  end
15
73
 
16
- def save
74
+ # Returns true if this object hasn't been saved yet -- that is, a resource
75
+ # for the object doesn't exist at the server yet; otherwise, returns false.
76
+ def new_resource?
77
+ @new_resource
78
+ end
79
+
80
+ alias_method :new?, :new_resource?
81
+ alias_method :new_record?, :new_resource?
82
+
83
+ # Returns true if this object has been destroyed, otherwise returns false.
84
+ def destroyed?
85
+ @destroyed
86
+ end
87
+
88
+ # Returns true if the resource is persisted, i.e. it's not a new resource
89
+ # and it was not destroyed, otherwise returns false.
90
+ def persisted?
91
+ !(new_resource? || destroyed?)
92
+ end
93
+
94
+ # Saves the resource at the server.
95
+ #
96
+ # If the model is new a resource gets created at the server, otherwise
97
+ # the existing resource gets updated.
98
+ #
99
+ # By default, save always run validations. If any of them fail the action
100
+ # is cancelled and +save+ returns +false+. However, if you supply
101
+ # validate: false, validations are bypassed altogether. See
102
+ # ActiveModel::Validations for more information.
103
+ #
104
+ # There's a series of callbacks associated with +save+. If any of the
105
+ # <tt>before_*</tt> callbacks return +false+ the action is cancelled and
106
+ # +save+ returns +false+. See ActiveModel::Callbacks for further
107
+ # details.
108
+ #
109
+ # Attributes marked as readonly are silently ignored if the resource is
110
+ # being updated.
111
+ def save(*)
17
112
  run_callbacks :save do
18
113
  @previously_changed = changes
19
- result = self.new_resource? ? self.create : self.update
114
+ result = create_or_update
20
115
  @changed_attributes.clear
21
116
  result
22
117
  end
23
118
  end
24
119
 
120
+ # Saves the model.
121
+ #
122
+ # If the model is new a resource gets created at the server, otherwise
123
+ # the existing resource gets updated.
124
+ #
125
+ # With <tt>save!</tt> validations always run. If any of them fail
126
+ # ActiveModel::resourceInvalid gets raised. See ActiveModel::Validations
127
+ # for more information.
128
+ #
129
+ # There's a series of callbacks associated with <tt>save!</tt>. If any of
130
+ # the <tt>before_*</tt> callbacks return +false+ the action is cancelled
131
+ # and <tt>save!</tt> raises ActiveModel::resourceNotSaved. See
132
+ # ActiveModel::Callbacks for further details.
133
+ #
134
+ # Attributes marked as readonly are silently ignored if the resource is
135
+ # being updated.
136
+ def save!(*)
137
+ create_or_update || raise(resourceNotSaved.new(nil, self))
138
+ end
139
+
140
+ # Deletes the resource at the server and freezes this instance to
141
+ # reflect that no changes should be made (since they can't be
142
+ # persisted). Returns the frozen instance.
143
+ #
144
+ # The row is simply removed with an SQL +DELETE+ statement on the
145
+ # resource's primary key, and no callbacks are executed.
146
+ #
147
+ # To enforce the object's +before_destroy+ and +after_destroy+
148
+ # callbacks or any <tt>:dependent</tt> association
149
+ # options, use <tt>#destroy</tt>.
150
+ def delete
151
+ self.class.delete(id) if persisted?
152
+ @destroyed = true
153
+ freeze
154
+ end
155
+
156
+ # Deletes the resource at the server and freezes this instance to reflect
157
+ # that no changes should be made (since they can't be persisted).
158
+ #
159
+ # There's a series of callbacks associated with <tt>destroy</tt>. If
160
+ # the <tt>before_destroy</tt> callback return +false+ the action is cancelled
161
+ # and <tt>destroy</tt> returns +false+. See
162
+ # Activeresource::Callbacks for further details.
25
163
  def destroy
26
164
  run_callbacks :destroy do
27
- #raise ReadOnlyRecord if readonly?
165
+ #raise ReadOnlyresource if readonly?
28
166
  #destroy_associations
29
167
  self.class.delete(self.id) if persisted?
30
168
  @destroyed = true
@@ -32,14 +170,74 @@ module NaranyaEcm::Rest
32
170
  end
33
171
  end
34
172
 
35
- def new_resource?; self.id.nil?; end
36
- alias_method :new?, :new_resource?
37
- alias_method :new_record?, :new_resource?
173
+ # Deletes the resource at the server and freezes this instance to reflect
174
+ # that no changes should be made (since they can't be persisted).
175
+ #
176
+ # There's a series of callbacks associated with <tt>destroy!</tt>. If
177
+ # the <tt>before_destroy</tt> callback return +false+ the action is cancelled
178
+ # and <tt>destroy!</tt> raises Activeresource::resourceNotDestroyed. See
179
+ # Activeresource::Callbacks for further details.
180
+ def destroy!
181
+ destroy || raise(ResourceNotDestroyed, self)
182
+ end
183
+
184
+ # Updates a single attribute and saves the resource.
185
+ # This is especially useful for boolean flags on existing resources.
186
+ # Also note that
187
+ #
188
+ # * Validation is skipped.
189
+ # * Callbacks are invoked.
190
+ # * updated_at/updated_on attribute is updated if that attribute is available.
191
+ # * Updates all the attributes that are dirty in this object.
192
+ #
193
+ # This method raises an +Activeresource::ActiveresourceError+ if the
194
+ # attribute is marked as readonly.
195
+ #
196
+ # See also +update_column+.
197
+ def update_attribute(name, value)
198
+ name = name.to_s
199
+ #verify_readonly_attribute(name)
200
+ send("#{name}=", value)
201
+ save(validate: false)
202
+ end
203
+
204
+ # Updates the attributes of the model from the passed-in hash and saves the
205
+ # resource, all wrapped in a transaction. If the object is invalid, the
206
+ # saving will fail and false will be returned.
207
+ def update(attributes)
208
+ assign_attributes(attributes)
209
+ save
210
+ end
211
+
212
+ def assign_attributes(given_attributes)
213
+ given_attributes.each do |key, val|
214
+ self.public_send "#{key}=", val
215
+ end
216
+ end
217
+
218
+ alias update_attributes update
38
219
 
39
- def persisted?; !new_resource? || !self.changed?; end
220
+ # Updates its receiver just like +update+ but calls <tt>save!</tt> instead
221
+ # of +save+, so an exception is raised if the resource is invalid.
222
+ def update!(attributes)
223
+ # The following transaction covers any possible server side-effects of the
224
+ # attributes assignment. For example, setting the IDs of a child collection.
225
+ with_transaction_returning_status do
226
+ assign_attributes(attributes)
227
+ save!
228
+ end
229
+ end
230
+
231
+ alias update_attributes! update!
40
232
 
41
233
  protected
42
234
 
235
+ def create_or_update
236
+ raise ReadOnlyResource, "#{self.class} is marked as readonly" if readonly?
237
+ result = new_resource? ? _create_resource : _update_resource
238
+ result != false
239
+ end
240
+
43
241
  def load_server_errors(server_error_hash)
44
242
  server_error_hash = server_error_hash.with_indifferent_access
45
243
  if server_error_hash.present? && server_error_hash.has_key?(:errors) && server_error_hash[:errors].present?
@@ -54,10 +252,10 @@ module NaranyaEcm::Rest
54
252
  end
55
253
 
56
254
  def reload
57
- format = NaranyaEcm.options[:format] || 'json'
58
- response = Client.get "#{path}.#{format}"
59
-
60
- load(response.to_hash)
255
+ response = NContent::SDK::RESTClient.get "#{path}.json"
256
+
257
+ load(response.body)
258
+ @new_resource = false
61
259
  true
62
260
  end
63
261
 
@@ -70,24 +268,31 @@ module NaranyaEcm::Rest
70
268
  }
71
269
  end
72
270
 
73
- def create
271
+ def _create_resource
74
272
  run_callbacks :create do
75
273
 
76
- format = NaranyaEcm.options[:format] || 'json'
77
- create_path = "#{self.class.path}.#{format}"
274
+ create_path = "#{self.class.path}.json"
78
275
 
79
276
  begin
80
- response = Client.post create_path, persist_request_options(self.attributes)
81
- self.load(response.to_hash)
277
+
278
+ response = NContent::SDK::RESTClient.post create_path do |req|
279
+ req.headers[:content_type] = 'application/json'
280
+ req.body = ActiveSupport::JSON.encode(
281
+ self.class.name.demodulize.underscore => attributes
282
+ )
283
+ end
284
+
285
+ self.load(response.body)
286
+ @new_resource = false
82
287
  true
83
288
  rescue UnprocessableEntity => e
84
- self.load_server_errors(e.response.to_hash)
289
+ self.load_server_errors(e.response.body)
85
290
  false
86
291
  end
87
292
  end
88
293
  end
89
294
 
90
- def update
295
+ def _update_resource
91
296
  run_callbacks :update do
92
297
 
93
298
  unless @is_touch
@@ -101,43 +306,26 @@ module NaranyaEcm::Rest
101
306
 
102
307
  attributes_to_save.merge! off_band_changes
103
308
 
104
- format = NaranyaEcm.options[:format] || 'json'
105
- update_path = "#{self.path}.#{format}"
309
+ update_path = "#{self.path}.json"
106
310
 
107
311
  begin
108
- response = Client.put update_path, persist_request_options(attributes_to_save)
312
+ response = NContent::SDK::RESTClient.put update_path do |req|
313
+ req.headers[:content_type] = 'application/json'
314
+ req.body = ActiveSupport::JSON.encode(
315
+ self.class.name.demodulize.underscore => attributes_to_save
316
+ )
317
+ end
318
+
109
319
  self.reload!
110
320
  off_band_changes.clear if off_band_changes.present?
111
321
  true
112
322
  rescue UnprocessableEntity
113
- self.load_server_errors(response.to_hash)
323
+ self.load_server_errors(response.body)
114
324
  false
115
325
  end
116
326
  end
117
327
  end
118
328
 
119
-
120
- module ClassMethods
121
-
122
- def create(attributes={})
123
- object_to_create = self.new attributes
124
- object_to_create.save
125
- object_to_create
126
- end
127
-
128
- def create!(attributes={})
129
- created_object = create(attributes)
130
- raise "ValidationError" unless created_object.persisted?
131
- created_object
132
- end
133
-
134
- def delete(id, options={})
135
- response = Client.delete("#{self.path}/#{id}.json")
136
- true
137
- end
138
-
139
- end
140
-
141
329
  end
142
330
 
143
- end
331
+ end