activeresource 6.1.4 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/lib/active_resource/active_job_serializer.rb +3 -4
- data/lib/active_resource/associations/builder/association.rb +1 -1
- data/lib/active_resource/associations/builder/belongs_to.rb +1 -1
- data/lib/active_resource/base.rb +38 -7
- data/lib/active_resource/coder.rb +76 -0
- data/lib/active_resource/collection.rb +1 -1
- data/lib/active_resource/connection.rb +10 -4
- data/lib/active_resource/exceptions.rb +3 -0
- data/lib/active_resource/formats.rb +5 -1
- data/lib/active_resource/http_mock.rb +4 -4
- data/lib/active_resource/log_subscriber.rb +1 -1
- data/lib/active_resource/railtie.rb +12 -0
- data/lib/active_resource/rescuable.rb +26 -0
- data/lib/active_resource/schema.rb +1 -1
- data/lib/active_resource/serialization.rb +81 -0
- data/lib/active_resource/validations.rb +1 -1
- data/lib/active_resource/version.rb +3 -3
- data/lib/active_resource/where_clause.rb +47 -0
- data/lib/active_resource.rb +6 -0
- metadata +14 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 56d3dcccc623568664d512654a732adb1c7f4a254ab04e265ac1399d0e4c1967
|
4
|
+
data.tar.gz: d58a56b898820598bde4e7f285120623f91cd4abf16f5e9487b52922780b9dc1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f3347abdf46c203bc277274a0f3f308e8582137a91471ae4ef2064acd7f869a1d12ce020e8031bee2ec710dfecd9933e4b5718ae3a3181116f08ccb5a5839305
|
7
|
+
data.tar.gz: c81b3391288de5f1031a6372354555d7cdad9f117e68193094b728e8e9851e35fbcea41a4b9b977b1338cad30095680935e9eb30c7ceee9e7d338ddf160ae660
|
data/README.md
CHANGED
@@ -4,7 +4,7 @@ module ActiveResource::Associations::Builder
|
|
4
4
|
class Association # :nodoc:
|
5
5
|
# providing a Class-Variable, which will have a different store of subclasses
|
6
6
|
class_attribute :valid_options
|
7
|
-
self.valid_options = [:class_name]
|
7
|
+
self.valid_options = [ :class_name ]
|
8
8
|
|
9
9
|
# would identify subclasses of association
|
10
10
|
class_attribute :macro
|
data/lib/active_resource/base.rb
CHANGED
@@ -886,6 +886,31 @@ module ActiveResource
|
|
886
886
|
"#{prefix(prefix_options)}#{collection_name}#{format_extension}#{query_string(query_options)}"
|
887
887
|
end
|
888
888
|
|
889
|
+
# Gets the collection URL for the REST resources. If the +query_options+ parameter is omitted, Rails
|
890
|
+
# will split from the +prefix_options+.
|
891
|
+
#
|
892
|
+
# ==== Options
|
893
|
+
# * +prefix_options+ - A hash to add a prefix to the request for nested URLs (e.g., <tt>:account_id => 19</tt>
|
894
|
+
# would yield a URL like <tt>/accounts/19/purchases.json</tt>).
|
895
|
+
# * +query_options+ - A hash to add items to the query string for the request.
|
896
|
+
#
|
897
|
+
# ==== Examples
|
898
|
+
# Post.collection_url
|
899
|
+
# # => https://example.com/posts.json
|
900
|
+
#
|
901
|
+
# Comment.collection_url(:post_id => 5)
|
902
|
+
# # => https://example.com/posts/5/comments.json
|
903
|
+
#
|
904
|
+
# Comment.collection_url(:post_id => 5, :active => 1)
|
905
|
+
# # => https://example.com/posts/5/comments.json?active=1
|
906
|
+
#
|
907
|
+
# Comment.collection_url({:post_id => 5}, {:active => 1})
|
908
|
+
# # => https://example.com/posts/5/comments.json?active=1
|
909
|
+
#
|
910
|
+
def collection_url(prefix_options = {}, query_options = nil)
|
911
|
+
URI.join(site, collection_path(prefix_options, query_options)).to_s
|
912
|
+
end
|
913
|
+
|
889
914
|
alias_method :set_primary_key, :primary_key= # :nodoc:
|
890
915
|
|
891
916
|
# Builds a new, unsaved record using the default values from the remote server so
|
@@ -1037,12 +1062,13 @@ module ActiveResource
|
|
1037
1062
|
# This is an alias for find(:all). You can pass in all the same
|
1038
1063
|
# arguments to this method as you can to <tt>find(:all)</tt>
|
1039
1064
|
def all(*args)
|
1040
|
-
|
1065
|
+
WhereClause.new(self, *args)
|
1041
1066
|
end
|
1042
1067
|
|
1043
1068
|
def where(clauses = {})
|
1069
|
+
clauses = sanitize_forbidden_attributes(clauses)
|
1044
1070
|
raise ArgumentError, "expected a clauses Hash, got #{clauses.inspect}" unless clauses.is_a? Hash
|
1045
|
-
|
1071
|
+
all(params: clauses)
|
1046
1072
|
end
|
1047
1073
|
|
1048
1074
|
|
@@ -1443,6 +1469,8 @@ module ActiveResource
|
|
1443
1469
|
# my_branch.name # => "Wilson Road"
|
1444
1470
|
def reload
|
1445
1471
|
self.load(self.class.find(to_param, params: @prefix_options).attributes, false, true)
|
1472
|
+
rescue => exception
|
1473
|
+
rescue_with_handler(exception) || raise
|
1446
1474
|
end
|
1447
1475
|
|
1448
1476
|
# A method to manually load attributes from a \hash. Recursively loads collections of
|
@@ -1471,6 +1499,7 @@ module ActiveResource
|
|
1471
1499
|
raise ArgumentError, "expected attributes to be able to convert to Hash, got #{attributes.inspect}"
|
1472
1500
|
end
|
1473
1501
|
|
1502
|
+
attributes = sanitize_forbidden_attributes(attributes)
|
1474
1503
|
attributes = attributes.to_hash
|
1475
1504
|
@prefix_options, attributes = split_options(attributes)
|
1476
1505
|
|
@@ -1627,7 +1656,7 @@ module ActiveResource
|
|
1627
1656
|
private
|
1628
1657
|
# Determine whether the response is allowed to have a body per HTTP 1.1 spec section 4.4.1
|
1629
1658
|
def response_code_allows_body?(c)
|
1630
|
-
!((100..199).include?(c) || [204, 304].include?(c))
|
1659
|
+
!((100..199).include?(c) || [ 204, 304 ].include?(c))
|
1631
1660
|
end
|
1632
1661
|
|
1633
1662
|
# Tries to find a resource for a given collection name; if it fails, then the resource is created
|
@@ -1643,7 +1672,7 @@ module ActiveResource
|
|
1643
1672
|
namespaces = module_names[0, module_names.size - 1].map do |module_name|
|
1644
1673
|
receiver = receiver.const_get(module_name)
|
1645
1674
|
end
|
1646
|
-
const_args = [resource_name, false]
|
1675
|
+
const_args = [ resource_name, false ]
|
1647
1676
|
if namespace = namespaces.reverse.detect { |ns| ns.const_defined?(*const_args) }
|
1648
1677
|
namespace.const_get(*const_args)
|
1649
1678
|
else
|
@@ -1656,7 +1685,7 @@ module ActiveResource
|
|
1656
1685
|
return reflections[name.to_sym].klass if reflections.key?(name.to_sym)
|
1657
1686
|
resource_name = name.to_s.camelize
|
1658
1687
|
|
1659
|
-
const_args = [resource_name, false]
|
1688
|
+
const_args = [ resource_name, false ]
|
1660
1689
|
|
1661
1690
|
if !const_valid?(*const_args)
|
1662
1691
|
# resource_name is not a valid ruby module name and cannot be created normally
|
@@ -1718,14 +1747,16 @@ module ActiveResource
|
|
1718
1747
|
end
|
1719
1748
|
|
1720
1749
|
class Base
|
1750
|
+
extend ActiveModel::ForbiddenAttributesProtection
|
1721
1751
|
extend ActiveModel::Naming
|
1722
1752
|
extend ActiveResource::Associations
|
1723
1753
|
|
1724
|
-
include Callbacks, CustomMethods, Validations
|
1754
|
+
include Callbacks, CustomMethods, Validations, Serialization
|
1725
1755
|
include ActiveModel::Conversion
|
1756
|
+
include ActiveModel::ForbiddenAttributesProtection
|
1726
1757
|
include ActiveModel::Serializers::JSON
|
1727
1758
|
include ActiveModel::Serializers::Xml
|
1728
|
-
include ActiveResource::Reflection
|
1759
|
+
include ActiveResource::Reflection, ActiveResource::Rescuable
|
1729
1760
|
end
|
1730
1761
|
|
1731
1762
|
ActiveSupport.run_load_hooks(:active_resource, Base)
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveResource
|
4
|
+
# Integrates with Active Record's
|
5
|
+
# {serialize}[link:https://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html#method-i-serialize]
|
6
|
+
# method as the <tt>:coder</tt> option.
|
7
|
+
#
|
8
|
+
# Encodes Active Resource instances into a value to be stored in the
|
9
|
+
# database. Decodes values read from the database into Active Resource
|
10
|
+
# instances.
|
11
|
+
#
|
12
|
+
# class User < ActiveRecord::Base
|
13
|
+
# serialize :person, coder: ActiveResource::Coder.new(Person)
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# class Person < ActiveResource::Base
|
17
|
+
# schema do
|
18
|
+
# attribute :name, :string
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# user = User.new
|
23
|
+
# user.person = Person.new name: "Matz"
|
24
|
+
# user.person.name # => "Matz"
|
25
|
+
#
|
26
|
+
# Values are loaded as persisted when decoded from data containing a
|
27
|
+
# primary key value, and new records when missing a primary key value:
|
28
|
+
#
|
29
|
+
# user.person = Person.new
|
30
|
+
# user.person.persisted? # => true
|
31
|
+
#
|
32
|
+
# user.person = Person.find(1)
|
33
|
+
# user.person.persisted? # => true
|
34
|
+
#
|
35
|
+
# By default, <tt>#dump</tt> serializes the instance to a string value by
|
36
|
+
# calling Base#encode:
|
37
|
+
#
|
38
|
+
# user.person_before_type_cast # => "{\"name\":\"Matz\"}"
|
39
|
+
#
|
40
|
+
# To customize serialization, pass the method name or a block as the second
|
41
|
+
# argument:
|
42
|
+
#
|
43
|
+
# person = Person.new name: "Matz"
|
44
|
+
#
|
45
|
+
# coder = ActiveResource::Coder.new(Person, :serializable_hash)
|
46
|
+
# coder.dump(person) # => { "name" => "Matz" }
|
47
|
+
#
|
48
|
+
# coder = ActiveResource::Coder.new(Person) { |person| person.serializable_hash }
|
49
|
+
# coder.dump(person) # => { "name" => "Matz" }
|
50
|
+
class Coder
|
51
|
+
attr_accessor :resource_class, :encoder
|
52
|
+
|
53
|
+
def initialize(resource_class, encoder_method = :encode, &block)
|
54
|
+
@resource_class = resource_class
|
55
|
+
@encoder = block || encoder_method
|
56
|
+
end
|
57
|
+
|
58
|
+
# Serializes a resource value to a value that will be stored in the database.
|
59
|
+
# Returns nil when passed nil
|
60
|
+
def dump(value)
|
61
|
+
return if value.nil?
|
62
|
+
raise ArgumentError.new("expected value to be #{resource_class}, but was #{value.class}") unless value.is_a?(resource_class)
|
63
|
+
|
64
|
+
value.yield_self(&encoder)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Deserializes a value from the database to a resource instance.
|
68
|
+
# Returns nil when passed nil
|
69
|
+
def load(value)
|
70
|
+
return if value.nil?
|
71
|
+
value = resource_class.format.decode(value) if value.is_a?(String)
|
72
|
+
raise ArgumentError.new("expected value to be Hash, but was #{value.class}") unless value.is_a?(Hash)
|
73
|
+
resource_class.new(value, value[resource_class.primary_key])
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -5,7 +5,7 @@ require "active_support/inflector"
|
|
5
5
|
|
6
6
|
module ActiveResource # :nodoc:
|
7
7
|
class Collection # :nodoc:
|
8
|
-
SELF_DEFINE_METHODS = [:to_a, :collect!, :map!, :all?]
|
8
|
+
SELF_DEFINE_METHODS = [ :to_a, :collect!, :map!, :all? ]
|
9
9
|
include Enumerable
|
10
10
|
delegate :to_yaml, :all?, *(Array.instance_methods(false) - SELF_DEFINE_METHODS), to: :to_a
|
11
11
|
|
@@ -116,9 +116,13 @@ module ActiveResource
|
|
116
116
|
private
|
117
117
|
# Makes a request to the remote service.
|
118
118
|
def request(method, path, *arguments)
|
119
|
+
body, headers = arguments
|
120
|
+
headers, body = body, nil if headers.nil?
|
119
121
|
result = ActiveSupport::Notifications.instrument("request.active_resource") do |payload|
|
120
122
|
payload[:method] = method
|
121
123
|
payload[:request_uri] = "#{site.scheme}://#{site.host}:#{site.port}#{path}"
|
124
|
+
payload[:headers] = headers
|
125
|
+
payload[:body] = body
|
122
126
|
payload[:result] = http.send(method, path, *arguments)
|
123
127
|
end
|
124
128
|
handle_response(result)
|
@@ -126,6 +130,8 @@ module ActiveResource
|
|
126
130
|
raise TimeoutError.new(e.message)
|
127
131
|
rescue OpenSSL::SSL::SSLError => e
|
128
132
|
raise SSLError.new(e.message)
|
133
|
+
rescue Errno::ECONNREFUSED => e
|
134
|
+
raise ConnectionRefusedError.new(e.message)
|
129
135
|
end
|
130
136
|
|
131
137
|
# Handles response and error codes from the remote service.
|
@@ -234,7 +240,7 @@ module ActiveResource
|
|
234
240
|
if auth_type == :digest
|
235
241
|
{ "Authorization" => digest_auth_header(http_method, uri) }
|
236
242
|
else
|
237
|
-
{ "Authorization" => "Basic " + ["#{@user}:#{@password}"].pack("m").delete("\r\n") }
|
243
|
+
{ "Authorization" => "Basic " + [ "#{@user}:#{@password}" ].pack("m").delete("\r\n") }
|
238
244
|
end
|
239
245
|
elsif @bearer_token
|
240
246
|
{ "Authorization" => "Bearer #{@bearer_token}" }
|
@@ -253,7 +259,7 @@ module ActiveResource
|
|
253
259
|
ha2 = Digest::MD5.hexdigest("#{http_method.to_s.upcase}:#{request_uri}")
|
254
260
|
|
255
261
|
params["cnonce"] = client_nonce
|
256
|
-
request_digest = Digest::MD5.hexdigest([ha1, params["nonce"], "0", params["cnonce"], params["qop"], ha2].join(":"))
|
262
|
+
request_digest = Digest::MD5.hexdigest([ ha1, params["nonce"], "0", params["cnonce"], params["qop"], ha2 ].join(":"))
|
257
263
|
"Digest #{auth_attributes_for(uri, request_digest, params)}"
|
258
264
|
end
|
259
265
|
|
@@ -279,7 +285,7 @@ module ActiveResource
|
|
279
285
|
%Q(nonce="#{params['nonce']}"),
|
280
286
|
'nc="0"',
|
281
287
|
%Q(cnonce="#{params['cnonce']}"),
|
282
|
-
%Q(response="#{request_digest}")]
|
288
|
+
%Q(response="#{request_digest}") ]
|
283
289
|
|
284
290
|
auth_attrs << %Q(opaque="#{params['opaque']}") unless params["opaque"].blank?
|
285
291
|
auth_attrs.join(", ")
|
@@ -292,7 +298,7 @@ module ActiveResource
|
|
292
298
|
def legitimize_auth_type(auth_type)
|
293
299
|
return :basic if auth_type.nil?
|
294
300
|
auth_type = auth_type.to_sym
|
295
|
-
auth_type.in?([:basic, :digest, :bearer]) ? auth_type : :basic
|
301
|
+
auth_type.in?([ :basic, :digest, :bearer ]) ? auth_type : :basic
|
296
302
|
end
|
297
303
|
end
|
298
304
|
end
|
@@ -10,7 +10,11 @@ module ActiveResource
|
|
10
10
|
# ActiveResource::Formats[:xml] # => ActiveResource::Formats::XmlFormat
|
11
11
|
# ActiveResource::Formats[:json] # => ActiveResource::Formats::JsonFormat
|
12
12
|
def self.[](mime_type_reference)
|
13
|
-
|
13
|
+
case mime_type_reference.to_s
|
14
|
+
when "xml" then XmlFormat
|
15
|
+
when "json" then JsonFormat
|
16
|
+
else ActiveResource::Formats.const_get(ActiveSupport::Inflector.camelize(mime_type_reference.to_s) + "Format")
|
17
|
+
end
|
14
18
|
end
|
15
19
|
|
16
20
|
def self.remove_root(data)
|
@@ -241,8 +241,8 @@ module ActiveResource
|
|
241
241
|
end
|
242
242
|
|
243
243
|
# body? methods
|
244
|
-
{ true => %w
|
245
|
-
false => %w
|
244
|
+
{ true => %w[post patch put],
|
245
|
+
false => %w[get delete head] }.each do |has_body, methods|
|
246
246
|
methods.each do |method|
|
247
247
|
# def post(path, body, headers, options = {})
|
248
248
|
# request = ActiveResource::Request.new(:post, path, body, headers, options)
|
@@ -375,11 +375,11 @@ module ActiveResource
|
|
375
375
|
end
|
376
376
|
|
377
377
|
def unstub_http?
|
378
|
-
HttpMock.net_connection_enabled? && defined?(@http)
|
378
|
+
HttpMock.net_connection_enabled? && (!defined?(@http) || @http.kind_of?(HttpMock))
|
379
379
|
end
|
380
380
|
|
381
381
|
def stub_http?
|
382
|
-
HttpMock.net_connection_disabled? && defined?(@http)
|
382
|
+
HttpMock.net_connection_disabled? && (!defined?(@http) || @http.kind_of?(Net::HTTP))
|
383
383
|
end
|
384
384
|
end
|
385
385
|
end
|
@@ -14,7 +14,7 @@ module ActiveResource
|
|
14
14
|
log_level_method = code.to_i < 400 ? :info : :error
|
15
15
|
|
16
16
|
send log_level_method, "#{event.payload[:method].to_s.upcase} #{event.payload[:request_uri]}"
|
17
|
-
send log_level_method, "--> %d %s %d (%.1fms)" % [code, message, body.to_s.length, event.duration]
|
17
|
+
send log_level_method, "--> %d %s %d (%.1fms)" % [ code, message, body.to_s.length, event.duration ]
|
18
18
|
end
|
19
19
|
|
20
20
|
def logger
|
@@ -5,6 +5,8 @@ require "rails"
|
|
5
5
|
|
6
6
|
module ActiveResource
|
7
7
|
class Railtie < Rails::Railtie
|
8
|
+
config.eager_load_namespaces << ActiveResource
|
9
|
+
|
8
10
|
config.active_resource = ActiveSupport::OrderedOptions.new
|
9
11
|
|
10
12
|
initializer "active_resource.set_configs" do |app|
|
@@ -27,5 +29,15 @@ module ActiveResource
|
|
27
29
|
app.deprecators[:active_resource] = ActiveResource.deprecator
|
28
30
|
end
|
29
31
|
end
|
32
|
+
|
33
|
+
initializer "active_resource.logger" do
|
34
|
+
ActiveSupport.on_load(:active_resource) { self.logger ||= ::Rails.logger }
|
35
|
+
end
|
36
|
+
|
37
|
+
initializer "active_resource.http_mock" do
|
38
|
+
ActiveSupport.on_load(:active_support_test_case) do
|
39
|
+
teardown { ActiveResource::HttpMock.reset! }
|
40
|
+
end
|
41
|
+
end
|
30
42
|
end
|
31
43
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveResource
|
4
|
+
# = Active Resource \Rescuable
|
5
|
+
#
|
6
|
+
# Provides
|
7
|
+
# {rescue_from}[rdoc-ref:ActiveSupport::Rescuable::ClassMethods#rescue_from]
|
8
|
+
# for resources. Wraps calls over the network to handle configured errors.
|
9
|
+
module Rescuable
|
10
|
+
extend ActiveSupport::Concern
|
11
|
+
|
12
|
+
included do
|
13
|
+
include ActiveSupport::Rescuable
|
14
|
+
|
15
|
+
around_save :handle_exceptions
|
16
|
+
around_destroy :handle_exceptions
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def handle_exceptions
|
21
|
+
yield
|
22
|
+
rescue => exception
|
23
|
+
rescue_with_handler(exception) || raise
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -4,7 +4,7 @@ module ActiveResource # :nodoc:
|
|
4
4
|
class Schema # :nodoc:
|
5
5
|
# attributes can be known to be one of these types. They are easy to
|
6
6
|
# cast to/from.
|
7
|
-
KNOWN_ATTRIBUTE_TYPES = %w
|
7
|
+
KNOWN_ATTRIBUTE_TYPES = %w[ string text integer float decimal datetime timestamp time date binary boolean ]
|
8
8
|
|
9
9
|
# An array of attribute definitions, representing the attributes that
|
10
10
|
# have been defined.
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveResource
|
4
|
+
# Compatibilitiy with Active Record's
|
5
|
+
# {serialize}[link:https://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html#method-i-serialize]
|
6
|
+
# method as the <tt>:coder</tt> option.
|
7
|
+
#
|
8
|
+
# === Writing to String columns
|
9
|
+
#
|
10
|
+
# Encodes Active Resource instances into a string to be stored in the
|
11
|
+
# database. Decodes strings read from the database into Active Resource
|
12
|
+
# instances.
|
13
|
+
#
|
14
|
+
# class User < ActiveRecord::Base
|
15
|
+
# serialize :person, coder: Person
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# class Person < ActiveResource::Base
|
19
|
+
# schema do
|
20
|
+
# attribute :name, :string
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# user = User.new
|
25
|
+
# user.person = Person.new name: "Matz"
|
26
|
+
#
|
27
|
+
# Writing string values incorporates the Base.format:
|
28
|
+
#
|
29
|
+
# Person.format = :json
|
30
|
+
#
|
31
|
+
# user.person = Person.new name: "Matz"
|
32
|
+
# user.person_before_type_cast # => "{\"name\":\"Matz\"}"
|
33
|
+
#
|
34
|
+
# Person.format = :xml
|
35
|
+
#
|
36
|
+
# user.person = Person.new name: "Matz"
|
37
|
+
# user.person_before_type_cast # => "<?xml version=\"1.0\" encoding=\"UTF-8\"?><person><name>Matz</name></person>"
|
38
|
+
#
|
39
|
+
# Instances are loaded as persisted when decoded from data containing a
|
40
|
+
# primary key value, and new records when missing a primary key value:
|
41
|
+
#
|
42
|
+
# user.person = Person.new
|
43
|
+
# user.person.persisted? # => false
|
44
|
+
#
|
45
|
+
# user.person = Person.find(1)
|
46
|
+
# user.person.persisted? # => true
|
47
|
+
#
|
48
|
+
# === Writing to JSON and JSONB columns
|
49
|
+
#
|
50
|
+
# class User < ActiveRecord::Base
|
51
|
+
# serialize :person, coder: ActiveResource::Coder.new(Person, :serializable_hash)
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# class Person < ActiveResource::Base
|
55
|
+
# schema do
|
56
|
+
# attribute :name, :string
|
57
|
+
# end
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# user = User.new
|
61
|
+
# user.person = Person.new name: "Matz"
|
62
|
+
# user.person.name # => "Matz"
|
63
|
+
#
|
64
|
+
# user.person_before_type_cast # => {"name"=>"Matz"}
|
65
|
+
module Serialization
|
66
|
+
extend ActiveSupport::Concern
|
67
|
+
|
68
|
+
included do
|
69
|
+
class_attribute :coder, instance_accessor: false, instance_predicate: false
|
70
|
+
end
|
71
|
+
|
72
|
+
module ClassMethods
|
73
|
+
delegate :dump, :load, to: :coder
|
74
|
+
|
75
|
+
def inherited(subclass) # :nodoc:
|
76
|
+
super
|
77
|
+
subclass.coder = Coder.new(subclass)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -15,7 +15,7 @@ module ActiveResource
|
|
15
15
|
# or not (by passing true).
|
16
16
|
def from_array(messages, save_cache = false)
|
17
17
|
clear unless save_cache
|
18
|
-
humanized_attributes = Hash[@base.known_attributes.map { |attr_name| [attr_name.humanize, attr_name] }]
|
18
|
+
humanized_attributes = Hash[@base.known_attributes.map { |attr_name| [ attr_name.humanize, attr_name ] }]
|
19
19
|
messages.each do |message|
|
20
20
|
attr_message = humanized_attributes.keys.sort_by { |a| -a.length }.detect do |attr_name|
|
21
21
|
if message[0, attr_name.size + 1] == "#{attr_name} "
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveResource
|
4
|
+
class WhereClause < BasicObject # :nodoc:
|
5
|
+
delegate_missing_to :resources
|
6
|
+
|
7
|
+
def initialize(resource_class, options = {})
|
8
|
+
@resource_class = resource_class
|
9
|
+
@options = options
|
10
|
+
@resources = nil
|
11
|
+
@loaded = false
|
12
|
+
end
|
13
|
+
|
14
|
+
def where(clauses = {})
|
15
|
+
all(params: clauses)
|
16
|
+
end
|
17
|
+
|
18
|
+
def all(options = {})
|
19
|
+
WhereClause.new(@resource_class, @options.deep_merge(options))
|
20
|
+
end
|
21
|
+
|
22
|
+
def load
|
23
|
+
unless @loaded
|
24
|
+
@resources = @resource_class.find(:all, @options)
|
25
|
+
@loaded = true
|
26
|
+
end
|
27
|
+
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def reload
|
32
|
+
reset
|
33
|
+
load
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
def resources
|
38
|
+
load
|
39
|
+
@resources
|
40
|
+
end
|
41
|
+
|
42
|
+
def reset
|
43
|
+
@resources = nil
|
44
|
+
@loaded = false
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/active_resource.rb
CHANGED
@@ -37,15 +37,21 @@ module ActiveResource
|
|
37
37
|
|
38
38
|
autoload :Base
|
39
39
|
autoload :Callbacks
|
40
|
+
autoload :Coder
|
40
41
|
autoload :Connection
|
41
42
|
autoload :CustomMethods
|
42
43
|
autoload :Formats
|
43
44
|
autoload :HttpMock
|
45
|
+
autoload :Rescuable
|
44
46
|
autoload :Schema
|
47
|
+
autoload :Serialization
|
45
48
|
autoload :Singleton
|
46
49
|
autoload :InheritingHash
|
47
50
|
autoload :Validations
|
48
51
|
autoload :Collection
|
52
|
+
eager_autoload do
|
53
|
+
autoload :WhereClause
|
54
|
+
end
|
49
55
|
|
50
56
|
if ActiveSupport::VERSION::STRING >= "7.1"
|
51
57
|
def self.deprecator
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activeresource
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.
|
4
|
+
version: 6.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: activesupport
|
@@ -16,28 +15,28 @@ dependencies:
|
|
16
15
|
requirements:
|
17
16
|
- - ">="
|
18
17
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
18
|
+
version: '7.0'
|
20
19
|
type: :runtime
|
21
20
|
prerelease: false
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
23
22
|
requirements:
|
24
23
|
- - ">="
|
25
24
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
25
|
+
version: '7.0'
|
27
26
|
- !ruby/object:Gem::Dependency
|
28
27
|
name: activemodel
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
30
29
|
requirements:
|
31
30
|
- - ">="
|
32
31
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
32
|
+
version: '7.0'
|
34
33
|
type: :runtime
|
35
34
|
prerelease: false
|
36
35
|
version_requirements: !ruby/object:Gem::Requirement
|
37
36
|
requirements:
|
38
37
|
- - ">="
|
39
38
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
39
|
+
version: '7.0'
|
41
40
|
- !ruby/object:Gem::Dependency
|
42
41
|
name: activemodel-serializers-xml
|
43
42
|
requirement: !ruby/object:Gem::Requirement
|
@@ -112,6 +111,7 @@ files:
|
|
112
111
|
- lib/active_resource/associations/builder/has_one.rb
|
113
112
|
- lib/active_resource/base.rb
|
114
113
|
- lib/active_resource/callbacks.rb
|
114
|
+
- lib/active_resource/coder.rb
|
115
115
|
- lib/active_resource/collection.rb
|
116
116
|
- lib/active_resource/connection.rb
|
117
117
|
- lib/active_resource/custom_methods.rb
|
@@ -124,22 +124,24 @@ files:
|
|
124
124
|
- lib/active_resource/log_subscriber.rb
|
125
125
|
- lib/active_resource/railtie.rb
|
126
126
|
- lib/active_resource/reflection.rb
|
127
|
+
- lib/active_resource/rescuable.rb
|
127
128
|
- lib/active_resource/schema.rb
|
129
|
+
- lib/active_resource/serialization.rb
|
128
130
|
- lib/active_resource/singleton.rb
|
129
131
|
- lib/active_resource/threadsafe_attributes.rb
|
130
132
|
- lib/active_resource/validations.rb
|
131
133
|
- lib/active_resource/version.rb
|
134
|
+
- lib/active_resource/where_clause.rb
|
132
135
|
- lib/activeresource.rb
|
133
136
|
homepage: http://www.rubyonrails.org
|
134
137
|
licenses:
|
135
138
|
- MIT
|
136
139
|
metadata:
|
137
140
|
bug_tracker_uri: https://github.com/rails/activeresource/issues
|
138
|
-
changelog_uri: https://github.com/rails/activeresource/releases/tag/v6.
|
141
|
+
changelog_uri: https://github.com/rails/activeresource/releases/tag/v6.2.0
|
139
142
|
documentation_uri: http://rubydoc.info/gems/activeresource
|
140
|
-
source_code_uri: https://github.com/rails/activeresource/tree/v6.
|
143
|
+
source_code_uri: https://github.com/rails/activeresource/tree/v6.2.0
|
141
144
|
rubygems_mfa_required: 'true'
|
142
|
-
post_install_message:
|
143
145
|
rdoc_options: []
|
144
146
|
require_paths:
|
145
147
|
- lib
|
@@ -147,15 +149,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
147
149
|
requirements:
|
148
150
|
- - ">="
|
149
151
|
- !ruby/object:Gem::Version
|
150
|
-
version: 2.
|
152
|
+
version: 2.7.0
|
151
153
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
154
|
requirements:
|
153
155
|
- - ">="
|
154
156
|
- !ruby/object:Gem::Version
|
155
157
|
version: '0'
|
156
158
|
requirements: []
|
157
|
-
rubygems_version: 3.
|
158
|
-
signing_key:
|
159
|
+
rubygems_version: 3.6.7
|
159
160
|
specification_version: 4
|
160
161
|
summary: REST modeling framework (part of Rails).
|
161
162
|
test_files: []
|