activeresource 4.1.0 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activeresource might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.rdoc +16 -0
- data/lib/active_resource.rb +1 -3
- data/lib/active_resource/associations.rb +16 -13
- data/lib/active_resource/associations/builder/belongs_to.rb +1 -1
- data/lib/active_resource/associations/builder/has_many.rb +1 -1
- data/lib/active_resource/associations/builder/has_one.rb +1 -1
- data/lib/active_resource/base.rb +29 -11
- data/lib/active_resource/collection.rb +16 -9
- data/lib/active_resource/connection.rb +3 -4
- data/lib/active_resource/formats.rb +1 -1
- data/lib/active_resource/observing.rb +0 -31
- data/lib/active_resource/railtie.rb +0 -10
- data/lib/active_resource/reflection.rb +1 -1
- data/lib/active_resource/threadsafe_attributes.rb +16 -12
- data/lib/active_resource/validations.rb +2 -1
- data/lib/active_resource/version.rb +2 -2
- metadata +27 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f09e2bfd3d8332924184d674556d18d2d0533dcf
|
4
|
+
data.tar.gz: 5dbc9edf5003415fd3565692dffa8a6342d0a1b2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 27ba6aabd0eea02c3f2adb1d6d92311c94415d9ac32589f24abc517f1384a0ab6471717ab50e017a4993b069452f85e636053e3e49ffeb37c60873fcc4f9f671
|
7
|
+
data.tar.gz: 3c8c8780b50ada3328e3df5b0d544e19cc3977dd4199c750991f403e00cfaa9c45213328cfdc717ebb0d86bbd931bc8b48724f17d7c56d7f996c6ace763e0ad6
|
data/README.rdoc
CHANGED
@@ -30,6 +30,10 @@ Or added to a Gemfile:
|
|
30
30
|
|
31
31
|
gem 'activeresource'
|
32
32
|
|
33
|
+
For compatibility with Rails 5, use:
|
34
|
+
|
35
|
+
gem 'activeresource', github: 'rails/activeresource', branch: 'master'
|
36
|
+
|
33
37
|
Source code can be downloaded on GitHub
|
34
38
|
|
35
39
|
* https://github.com/rails/activeresource/tree/master/activeresource
|
@@ -53,6 +57,16 @@ life cycle methods that operate against a persistent store.
|
|
53
57
|
As you can see, the methods are quite similar to Active Record's methods for dealing with database
|
54
58
|
records. But rather than dealing directly with a database record, you're dealing with HTTP resources (which may or may not be database records).
|
55
59
|
|
60
|
+
==== Authentication
|
61
|
+
|
62
|
+
Active Resource supports the token based authentication provided by Rails through the <tt>ActionController::HttpAuthentication::Token</tt> class using custom headers.
|
63
|
+
|
64
|
+
class Person < ActiveResource::Base
|
65
|
+
self.headers['Authorization'] = 'Token token="abcd"'
|
66
|
+
end
|
67
|
+
|
68
|
+
You can also set any specific HTTP header using the same way.
|
69
|
+
|
56
70
|
==== Protocol
|
57
71
|
|
58
72
|
Active Resource is built on a standard JSON or XML format for requesting and submitting resources over HTTP. It mirrors the RESTful routing
|
@@ -123,6 +137,7 @@ as the id of the ARes object.
|
|
123
137
|
#
|
124
138
|
# is submitted as the body on
|
125
139
|
#
|
140
|
+
# if include_root_in_json is not set or set to false => {"first":"Tyler"}
|
126
141
|
# if include_root_in_json is set to true => {"person":{"first":"Tyler"}}
|
127
142
|
#
|
128
143
|
# POST http://api.people.com:3000/people.json
|
@@ -148,6 +163,7 @@ server side was successful.
|
|
148
163
|
#
|
149
164
|
# is submitted as the body on
|
150
165
|
#
|
166
|
+
# if include_root_in_json is not set or set to false => {"first":"Tyler"}
|
151
167
|
# if include_root_in_json is set to true => {"person":{"first":"Tyler"}}
|
152
168
|
#
|
153
169
|
# PUT http://api.people.com:3000/people/1.json
|
data/lib/active_resource.rb
CHANGED
@@ -35,12 +35,10 @@ module ActiveResource
|
|
35
35
|
autoload :CustomMethods
|
36
36
|
autoload :Formats
|
37
37
|
autoload :HttpMock
|
38
|
-
autoload :Observing
|
39
38
|
autoload :Schema
|
40
39
|
autoload :Singleton
|
41
40
|
autoload :Validations
|
42
41
|
autoload :Collection
|
43
42
|
end
|
44
43
|
|
45
|
-
require 'active_resource/railtie' if defined?
|
46
|
-
|
44
|
+
require 'active_resource/railtie' if defined?(Rails.application)
|
@@ -65,7 +65,7 @@ module ActiveResource::Associations
|
|
65
65
|
# Would resolve this author into the <tt>Myblog::Author</tt> class.
|
66
66
|
#
|
67
67
|
# If the response body does not contain an attribute matching the association name
|
68
|
-
# a request is sent to a
|
68
|
+
# a request is sent to a singleton path under the current resource.
|
69
69
|
# For example, if a Product class <tt>has_one :inventory</tt> calling <tt>Product#inventory</tt>
|
70
70
|
# will generate a request on /products/:product_id/inventory.json.
|
71
71
|
#
|
@@ -89,15 +89,15 @@ module ActiveResource::Associations
|
|
89
89
|
#
|
90
90
|
# === Example
|
91
91
|
#
|
92
|
-
# A Comment class
|
92
|
+
# A Comment class declares <tt>belongs_to :post</tt>, which will add:
|
93
93
|
# * <tt>Comment#post</tt> (similar to <tt>Post.find(post_id)</tt>)
|
94
94
|
# The declaration can also include an options hash to specialize the behavior of the association.
|
95
95
|
#
|
96
96
|
# === Options
|
97
97
|
# [:class_name]
|
98
|
-
# Specify the class name for the association. Use it only if that name
|
98
|
+
# Specify the class name for the association. Use it only if that name can't be inferred from association name.
|
99
99
|
# So <tt>belongs_to :post</tt> will by default be linked to the Post class, but if the real class name is Article,
|
100
|
-
# you'll have to specify it with
|
100
|
+
# you'll have to specify it with this option.
|
101
101
|
# [:foreign_key]
|
102
102
|
# Specify the foreign key used for the association. By default this is guessed to be the name
|
103
103
|
# of the association with an "_id" suffix. So a class that defines a <tt>belongs_to :post</tt>
|
@@ -117,7 +117,8 @@ module ActiveResource::Associations
|
|
117
117
|
end
|
118
118
|
|
119
119
|
# Defines the belongs_to association finder method
|
120
|
-
def defines_belongs_to_finder_method(
|
120
|
+
def defines_belongs_to_finder_method(reflection)
|
121
|
+
method_name = reflection.name
|
121
122
|
ivar_name = :"@#{method_name}"
|
122
123
|
|
123
124
|
if method_defined?(method_name)
|
@@ -130,13 +131,14 @@ module ActiveResource::Associations
|
|
130
131
|
instance_variable_get(ivar_name)
|
131
132
|
elsif attributes.include?(method_name)
|
132
133
|
attributes[method_name]
|
133
|
-
elsif association_id = send(
|
134
|
-
instance_variable_set(ivar_name,
|
134
|
+
elsif association_id = send(reflection.foreign_key)
|
135
|
+
instance_variable_set(ivar_name, reflection.klass.find(association_id))
|
135
136
|
end
|
136
137
|
end
|
137
138
|
end
|
138
139
|
|
139
|
-
def defines_has_many_finder_method(
|
140
|
+
def defines_has_many_finder_method(reflection)
|
141
|
+
method_name = reflection.name
|
140
142
|
ivar_name = :"@#{method_name}"
|
141
143
|
|
142
144
|
define_method(method_name) do
|
@@ -145,7 +147,7 @@ module ActiveResource::Associations
|
|
145
147
|
elsif attributes.include?(method_name)
|
146
148
|
attributes[method_name]
|
147
149
|
elsif !new_record?
|
148
|
-
instance_variable_set(ivar_name,
|
150
|
+
instance_variable_set(ivar_name, reflection.klass.find(:all, :params => {:"#{self.class.element_name}_id" => self.id}))
|
149
151
|
else
|
150
152
|
instance_variable_set(ivar_name, self.class.collection_parser.new)
|
151
153
|
end
|
@@ -153,7 +155,8 @@ module ActiveResource::Associations
|
|
153
155
|
end
|
154
156
|
|
155
157
|
# Defines the has_one association
|
156
|
-
def defines_has_one_finder_method(
|
158
|
+
def defines_has_one_finder_method(reflection)
|
159
|
+
method_name = reflection.name
|
157
160
|
ivar_name = :"@#{method_name}"
|
158
161
|
|
159
162
|
define_method(method_name) do
|
@@ -161,10 +164,10 @@ module ActiveResource::Associations
|
|
161
164
|
instance_variable_get(ivar_name)
|
162
165
|
elsif attributes.include?(method_name)
|
163
166
|
attributes[method_name]
|
164
|
-
elsif
|
165
|
-
instance_variable_set(ivar_name,
|
167
|
+
elsif reflection.klass.respond_to?(:singleton_name)
|
168
|
+
instance_variable_set(ivar_name, reflection.klass.find(:params => {:"#{self.class.element_name}_id" => self.id}))
|
166
169
|
else
|
167
|
-
instance_variable_set(ivar_name,
|
170
|
+
instance_variable_set(ivar_name, reflection.klass.find(:one, :from => "/#{self.class.collection_name}/#{self.id}/#{method_name}#{self.class.format_extension}"))
|
168
171
|
end
|
169
172
|
end
|
170
173
|
end
|
@@ -7,7 +7,7 @@ module ActiveResource::Associations::Builder
|
|
7
7
|
def build
|
8
8
|
validate_options
|
9
9
|
reflection = model.create_reflection(self.class.macro, name, options)
|
10
|
-
model.defines_belongs_to_finder_method(reflection
|
10
|
+
model.defines_belongs_to_finder_method(reflection)
|
11
11
|
return reflection
|
12
12
|
end
|
13
13
|
end
|
@@ -5,7 +5,7 @@ module ActiveResource::Associations::Builder
|
|
5
5
|
def build
|
6
6
|
validate_options
|
7
7
|
model.create_reflection(self.class.macro, name, options).tap do |reflection|
|
8
|
-
model.defines_has_many_finder_method(reflection
|
8
|
+
model.defines_has_many_finder_method(reflection)
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
@@ -5,7 +5,7 @@ module ActiveResource::Associations::Builder
|
|
5
5
|
def build
|
6
6
|
validate_options
|
7
7
|
model.create_reflection(self.class.macro, name, options).tap do |reflection|
|
8
|
-
model.defines_has_one_finder_method(reflection
|
8
|
+
model.defines_has_one_finder_method(reflection)
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
data/lib/active_resource/base.rb
CHANGED
@@ -20,6 +20,8 @@ require 'active_resource/associations'
|
|
20
20
|
require 'active_resource/reflection'
|
21
21
|
require 'active_resource/threadsafe_attributes'
|
22
22
|
|
23
|
+
require 'active_model/serializers/xml'
|
24
|
+
|
23
25
|
module ActiveResource
|
24
26
|
# ActiveResource::Base is the main class for mapping RESTful resources as models in a Rails application.
|
25
27
|
#
|
@@ -305,6 +307,8 @@ module ActiveResource
|
|
305
307
|
class_attribute :include_format_in_path
|
306
308
|
self.include_format_in_path = true
|
307
309
|
|
310
|
+
class_attribute :connection_class
|
311
|
+
self.connection_class = Connection
|
308
312
|
|
309
313
|
class << self
|
310
314
|
include ThreadsafeAttributes
|
@@ -379,7 +383,7 @@ module ActiveResource
|
|
379
383
|
@known_attributes << k
|
380
384
|
end
|
381
385
|
|
382
|
-
schema
|
386
|
+
@schema
|
383
387
|
else
|
384
388
|
@schema ||= nil
|
385
389
|
end
|
@@ -632,7 +636,7 @@ module ActiveResource
|
|
632
636
|
# or not (defaults to <tt>false</tt>).
|
633
637
|
def connection(refresh = false)
|
634
638
|
if _connection_defined? || superclass == Object
|
635
|
-
self._connection =
|
639
|
+
self._connection = connection_class.new(site, format) if refresh || _connection.nil?
|
636
640
|
_connection.proxy = proxy if proxy
|
637
641
|
_connection.user = user if user
|
638
642
|
_connection.password = password if password
|
@@ -648,11 +652,11 @@ module ActiveResource
|
|
648
652
|
end
|
649
653
|
|
650
654
|
def headers
|
651
|
-
self._headers
|
652
|
-
if superclass != Object
|
653
|
-
self._headers = superclass.headers.merge(
|
655
|
+
headers_state = self._headers || {}
|
656
|
+
if superclass != Object
|
657
|
+
self._headers = superclass.headers.merge(headers_state)
|
654
658
|
else
|
655
|
-
|
659
|
+
headers_state
|
656
660
|
end
|
657
661
|
end
|
658
662
|
|
@@ -852,6 +856,17 @@ module ActiveResource
|
|
852
856
|
self.new(attributes).tap { |resource| resource.save }
|
853
857
|
end
|
854
858
|
|
859
|
+
# Creates a new resource (just like <tt>create</tt>) and makes a request to the
|
860
|
+
# remote service that it be saved, but runs validations and raises
|
861
|
+
# <tt>ActiveResource::ResourceInvalid</tt>, making it equivalent to the following
|
862
|
+
# simultaneous calls:
|
863
|
+
#
|
864
|
+
# ryan = Person.new(:first => 'ryan')
|
865
|
+
# ryan.save!
|
866
|
+
def create!(attributes = {})
|
867
|
+
self.new(attributes).tap { |resource| resource.save! }
|
868
|
+
end
|
869
|
+
|
855
870
|
# Core method for finding resources. Used similarly to Active Record's +find+ method.
|
856
871
|
#
|
857
872
|
# ==== Arguments
|
@@ -981,7 +996,7 @@ module ActiveResource
|
|
981
996
|
prefix_options, query_options = split_options(options[:params])
|
982
997
|
path = element_path(id, prefix_options, query_options)
|
983
998
|
response = connection.head(path, headers)
|
984
|
-
response.code
|
999
|
+
(200..206).include? response.code
|
985
1000
|
end
|
986
1001
|
# id && !find_single(id, options).nil?
|
987
1002
|
rescue ActiveResource::ResourceNotFound, ActiveResource::ResourceGone
|
@@ -1370,7 +1385,11 @@ module ActiveResource
|
|
1370
1385
|
# your_supplier.load(my_attrs)
|
1371
1386
|
# your_supplier.save
|
1372
1387
|
def load(attributes, remove_root = false, persisted = false)
|
1373
|
-
|
1388
|
+
unless attributes.respond_to?(:to_hash)
|
1389
|
+
raise ArgumentError, "expected attributes to be able to convert to Hash, got #{attributes.inspect}"
|
1390
|
+
end
|
1391
|
+
|
1392
|
+
attributes = attributes.to_hash
|
1374
1393
|
@prefix_options, attributes = split_options(attributes)
|
1375
1394
|
|
1376
1395
|
if attributes.keys.size == 1
|
@@ -1438,7 +1457,7 @@ module ActiveResource
|
|
1438
1457
|
# A method to determine if an object responds to a message (e.g., a method call). In Active Resource, a Person object with a
|
1439
1458
|
# +name+ attribute can answer <tt>true</tt> to <tt>my_person.respond_to?(:name)</tt>, <tt>my_person.respond_to?(:name=)</tt>, and
|
1440
1459
|
# <tt>my_person.respond_to?(:name?)</tt>.
|
1441
|
-
def
|
1460
|
+
def respond_to_missing?(method, include_priv = false)
|
1442
1461
|
method_name = method.to_s
|
1443
1462
|
if attributes.nil?
|
1444
1463
|
super
|
@@ -1600,7 +1619,7 @@ module ActiveResource
|
|
1600
1619
|
extend ActiveModel::Naming
|
1601
1620
|
extend ActiveResource::Associations
|
1602
1621
|
|
1603
|
-
include Callbacks, CustomMethods,
|
1622
|
+
include Callbacks, CustomMethods, Validations
|
1604
1623
|
include ActiveModel::Conversion
|
1605
1624
|
include ActiveModel::Serializers::JSON
|
1606
1625
|
include ActiveModel::Serializers::Xml
|
@@ -1609,4 +1628,3 @@ module ActiveResource
|
|
1609
1628
|
|
1610
1629
|
ActiveSupport.run_load_hooks(:active_resource, Base)
|
1611
1630
|
end
|
1612
|
-
|
@@ -3,17 +3,18 @@ require 'active_support/inflector'
|
|
3
3
|
|
4
4
|
module ActiveResource # :nodoc:
|
5
5
|
class Collection # :nodoc:
|
6
|
+
SELF_DEFINE_METHODS = [:to_a, :collect!, :map!]
|
6
7
|
include Enumerable
|
7
|
-
delegate :to_yaml, :all?, *Array.instance_methods(false), :to => :to_a
|
8
|
+
delegate :to_yaml, :all?, *(Array.instance_methods(false) - SELF_DEFINE_METHODS), :to => :to_a
|
8
9
|
|
9
10
|
# The array of actual elements returned by index actions
|
10
11
|
attr_accessor :elements, :resource_class, :original_params
|
11
|
-
|
12
|
+
|
12
13
|
# ActiveResource::Collection is a wrapper to handle parsing index responses that
|
13
14
|
# do not directly map to Rails conventions.
|
14
15
|
#
|
15
16
|
# You can define a custom class that inherets from ActiveResource::Collection
|
16
|
-
# in order to to set the elements instance.
|
17
|
+
# in order to to set the elements instance.
|
17
18
|
#
|
18
19
|
# GET /posts.json delivers following response body:
|
19
20
|
# {
|
@@ -21,12 +22,12 @@ module ActiveResource # :nodoc:
|
|
21
22
|
# {
|
22
23
|
# title: "ActiveResource now has associations",
|
23
24
|
# body: "Lorem Ipsum"
|
24
|
-
# }
|
25
|
+
# },
|
25
26
|
# {...}
|
26
|
-
# ]
|
27
|
+
# ],
|
27
28
|
# next_page: "/posts.json?page=2"
|
28
29
|
# }
|
29
|
-
#
|
30
|
+
#
|
30
31
|
# A Post class can be setup to handle it with:
|
31
32
|
#
|
32
33
|
# class Post < ActiveResource::Base
|
@@ -44,7 +45,7 @@ module ActiveResource # :nodoc:
|
|
44
45
|
# end
|
45
46
|
# end
|
46
47
|
#
|
47
|
-
# The result from a find method that returns multiple entries will now be a
|
48
|
+
# The result from a find method that returns multiple entries will now be a
|
48
49
|
# PostParser instance. ActiveResource::Collection includes Enumerable and
|
49
50
|
# instances can be iterated over just like an array.
|
50
51
|
# @posts = Post.find(:all) # => PostCollection:xxx
|
@@ -56,11 +57,11 @@ module ActiveResource # :nodoc:
|
|
56
57
|
def initialize(elements = [])
|
57
58
|
@elements = elements
|
58
59
|
end
|
59
|
-
|
60
|
+
|
60
61
|
def to_a
|
61
62
|
elements
|
62
63
|
end
|
63
|
-
|
64
|
+
|
64
65
|
def collect!
|
65
66
|
return elements unless block_given?
|
66
67
|
set = []
|
@@ -81,5 +82,11 @@ module ActiveResource # :nodoc:
|
|
81
82
|
rescue NoMethodError
|
82
83
|
raise "Cannot build resource from resource type: #{resource_class.inspect}"
|
83
84
|
end
|
85
|
+
|
86
|
+
def where(clauses = {})
|
87
|
+
raise ArgumentError, "expected a clauses Hash, got #{clauses.inspect}" unless clauses.is_a? Hash
|
88
|
+
new_clauses = original_params.merge(clauses)
|
89
|
+
resource_class.where(new_clauses)
|
90
|
+
end
|
84
91
|
end
|
85
92
|
end
|
@@ -177,7 +177,9 @@ module ActiveResource
|
|
177
177
|
|
178
178
|
def new_http
|
179
179
|
if @proxy
|
180
|
-
|
180
|
+
user = URI.parser.unescape(@proxy.user) if @proxy.user
|
181
|
+
password = URI.parser.unescape(@proxy.password) if @proxy.password
|
182
|
+
Net::HTTP.new(@site.host, @site.port, @proxy.host, @proxy.port, user, password)
|
181
183
|
else
|
182
184
|
Net::HTTP.new(@site.host, @site.port)
|
183
185
|
end
|
@@ -201,9 +203,6 @@ module ActiveResource
|
|
201
203
|
if defined? @ssl_options
|
202
204
|
http.use_ssl = true
|
203
205
|
|
204
|
-
# Default to no cert verification (WTF? FIXME)
|
205
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
206
|
-
|
207
206
|
# All the SSL options have corresponding http settings.
|
208
207
|
@ssl_options.each { |key, value| http.send "#{key}=", value }
|
209
208
|
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
require 'rails/observers/active_model/observing'
|
2
|
-
|
3
|
-
module ActiveResource
|
4
|
-
module Observing
|
5
|
-
extend ActiveSupport::Concern
|
6
|
-
include ActiveModel::Observing
|
7
|
-
|
8
|
-
included do
|
9
|
-
%w( create save update destroy ).each do |method|
|
10
|
-
# def create_with_notifications(*args, &block)
|
11
|
-
# notify_observers(:before_create)
|
12
|
-
# if result = create_without_notifications(*args, &block)
|
13
|
-
# notify_observers(:after_create)
|
14
|
-
# end
|
15
|
-
# result
|
16
|
-
# end
|
17
|
-
# alias_method_chain(create, :notifications)
|
18
|
-
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
19
|
-
def #{method}_with_notifications(*args, &block)
|
20
|
-
notify_observers(:before_#{method})
|
21
|
-
if result = #{method}_without_notifications(*args, &block)
|
22
|
-
notify_observers(:after_#{method})
|
23
|
-
end
|
24
|
-
result
|
25
|
-
end
|
26
|
-
EOS
|
27
|
-
alias_method_chain(method, :notifications)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -10,16 +10,6 @@ module ActiveResource
|
|
10
10
|
ActiveResource::Base.send "#{k}=", v
|
11
11
|
end
|
12
12
|
end
|
13
|
-
|
14
|
-
config.after_initialize do |app|
|
15
|
-
ActiveSupport.on_load(:active_resource) do
|
16
|
-
ActiveResource::Base.instantiate_observers
|
17
|
-
|
18
|
-
ActionDispatch::Reloader.to_prepare do
|
19
|
-
ActiveResource::Base.instantiate_observers
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
13
|
end
|
24
14
|
end
|
25
15
|
|
@@ -66,7 +66,7 @@ module ActiveResource
|
|
66
66
|
|
67
67
|
private
|
68
68
|
def derive_class_name
|
69
|
-
return (options[:class_name] ? options[:class_name].to_s : name.to_s
|
69
|
+
return (options[:class_name] ? options[:class_name].to_s.camelize : name.to_s.classify)
|
70
70
|
end
|
71
71
|
|
72
72
|
def derive_foreign_key
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'active_support/core_ext/object/duplicable'
|
2
|
+
|
1
3
|
module ThreadsafeAttributes
|
2
4
|
def self.included(klass)
|
3
5
|
klass.extend(ClassMethods)
|
@@ -5,17 +7,19 @@ module ThreadsafeAttributes
|
|
5
7
|
|
6
8
|
module ClassMethods
|
7
9
|
def threadsafe_attribute(*attrs)
|
10
|
+
main_thread = Thread.main # remember this, because it could change after forking
|
11
|
+
|
8
12
|
attrs.each do |attr|
|
9
13
|
define_method attr do
|
10
|
-
get_threadsafe_attribute(attr)
|
14
|
+
get_threadsafe_attribute(attr, main_thread)
|
11
15
|
end
|
12
16
|
|
13
17
|
define_method "#{attr}=" do |value|
|
14
|
-
set_threadsafe_attribute(attr, value)
|
18
|
+
set_threadsafe_attribute(attr, value, main_thread)
|
15
19
|
end
|
16
20
|
|
17
21
|
define_method "#{attr}_defined?" do
|
18
|
-
threadsafe_attribute_defined?(attr)
|
22
|
+
threadsafe_attribute_defined?(attr, main_thread)
|
19
23
|
end
|
20
24
|
end
|
21
25
|
end
|
@@ -23,26 +27,26 @@ module ThreadsafeAttributes
|
|
23
27
|
|
24
28
|
private
|
25
29
|
|
26
|
-
def get_threadsafe_attribute(name)
|
30
|
+
def get_threadsafe_attribute(name, main_thread)
|
27
31
|
if threadsafe_attribute_defined_by_thread?(name, Thread.current)
|
28
32
|
get_threadsafe_attribute_by_thread(name, Thread.current)
|
29
|
-
elsif threadsafe_attribute_defined_by_thread?(name,
|
30
|
-
value = get_threadsafe_attribute_by_thread(name,
|
31
|
-
value = value.dup if value
|
33
|
+
elsif threadsafe_attribute_defined_by_thread?(name, main_thread)
|
34
|
+
value = get_threadsafe_attribute_by_thread(name, main_thread)
|
35
|
+
value = value.dup if value.duplicable?
|
32
36
|
set_threadsafe_attribute_by_thread(name, value, Thread.current)
|
33
37
|
value
|
34
38
|
end
|
35
39
|
end
|
36
40
|
|
37
|
-
def set_threadsafe_attribute(name, value)
|
41
|
+
def set_threadsafe_attribute(name, value, main_thread)
|
38
42
|
set_threadsafe_attribute_by_thread(name, value, Thread.current)
|
39
|
-
unless threadsafe_attribute_defined_by_thread?(name,
|
40
|
-
set_threadsafe_attribute_by_thread(name, value,
|
43
|
+
unless threadsafe_attribute_defined_by_thread?(name, main_thread)
|
44
|
+
set_threadsafe_attribute_by_thread(name, value, main_thread)
|
41
45
|
end
|
42
46
|
end
|
43
47
|
|
44
|
-
def threadsafe_attribute_defined?(name)
|
45
|
-
threadsafe_attribute_defined_by_thread?(name, Thread.current) || ((Thread.current !=
|
48
|
+
def threadsafe_attribute_defined?(name, main_thread)
|
49
|
+
threadsafe_attribute_defined_by_thread?(name, Thread.current) || ((Thread.current != main_thread) && threadsafe_attribute_defined_by_thread?(name, main_thread))
|
46
50
|
end
|
47
51
|
|
48
52
|
def get_threadsafe_attribute_by_thread(name, thread)
|
@@ -100,7 +100,8 @@ module ActiveResource
|
|
100
100
|
include ActiveModel::Validations
|
101
101
|
|
102
102
|
included do
|
103
|
-
|
103
|
+
alias_method :save_without_validation, :save
|
104
|
+
alias_method :save, :save_with_validation
|
104
105
|
end
|
105
106
|
|
106
107
|
# Validate a resource and save (POST) it to the remote web service.
|
metadata
CHANGED
@@ -1,57 +1,69 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activeresource
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-05-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '5.0'
|
20
|
+
- - "<"
|
18
21
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
22
|
+
version: '6'
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
|
-
- - "
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '5.0'
|
30
|
+
- - "<"
|
25
31
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
32
|
+
version: '6'
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: activemodel
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
30
36
|
requirements:
|
31
|
-
- - "
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '5.0'
|
40
|
+
- - "<"
|
32
41
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
42
|
+
version: '6'
|
34
43
|
type: :runtime
|
35
44
|
prerelease: false
|
36
45
|
version_requirements: !ruby/object:Gem::Requirement
|
37
46
|
requirements:
|
38
|
-
- - "
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '5.0'
|
50
|
+
- - "<"
|
39
51
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
52
|
+
version: '6'
|
41
53
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
54
|
+
name: activemodel-serializers-xml
|
43
55
|
requirement: !ruby/object:Gem::Requirement
|
44
56
|
requirements:
|
45
57
|
- - "~>"
|
46
58
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
59
|
+
version: '1.0'
|
48
60
|
type: :runtime
|
49
61
|
prerelease: false
|
50
62
|
version_requirements: !ruby/object:Gem::Requirement
|
51
63
|
requirements:
|
52
64
|
- - "~>"
|
53
65
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
66
|
+
version: '1.0'
|
55
67
|
- !ruby/object:Gem::Dependency
|
56
68
|
name: rake
|
57
69
|
requirement: !ruby/object:Gem::Requirement
|
@@ -129,7 +141,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
129
141
|
requirements:
|
130
142
|
- - ">="
|
131
143
|
- !ruby/object:Gem::Version
|
132
|
-
version:
|
144
|
+
version: 2.2.2
|
133
145
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
134
146
|
requirements:
|
135
147
|
- - ">="
|
@@ -137,7 +149,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
149
|
version: '0'
|
138
150
|
requirements: []
|
139
151
|
rubyforge_project:
|
140
|
-
rubygems_version: 2.5.
|
152
|
+
rubygems_version: 2.5.2
|
141
153
|
signing_key:
|
142
154
|
specification_version: 4
|
143
155
|
summary: REST modeling framework (part of Rails).
|