activeresource 5.0.0 → 5.1.1

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.
@@ -1,26 +1,28 @@
1
- require 'active_support'
2
- require 'active_support/core_ext/class/attribute_accessors'
3
- require 'active_support/core_ext/class/attribute'
4
- require 'active_support/core_ext/hash/indifferent_access'
5
- require 'active_support/core_ext/kernel/reporting'
6
- require 'active_support/core_ext/module/delegation'
7
- require 'active_support/core_ext/module/aliasing'
8
- require 'active_support/core_ext/object/blank'
9
- require 'active_support/core_ext/object/to_query'
10
- require 'active_support/core_ext/object/duplicable'
11
- require 'set'
12
- require 'uri'
13
-
14
- require 'active_support/core_ext/uri'
15
- require 'active_resource/connection'
16
- require 'active_resource/formats'
17
- require 'active_resource/schema'
18
- require 'active_resource/log_subscriber'
19
- require 'active_resource/associations'
20
- require 'active_resource/reflection'
21
- require 'active_resource/threadsafe_attributes'
22
-
23
- require 'active_model/serializers/xml'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support"
4
+ require "active_support/core_ext/class/attribute_accessors"
5
+ require "active_support/core_ext/class/attribute"
6
+ require "active_support/core_ext/hash/indifferent_access"
7
+ require "active_support/core_ext/kernel/reporting"
8
+ require "active_support/core_ext/module/delegation"
9
+ require "active_support/core_ext/module/aliasing"
10
+ require "active_support/core_ext/object/blank"
11
+ require "active_support/core_ext/object/to_query"
12
+ require "active_support/core_ext/object/duplicable"
13
+ require "set"
14
+ require "uri"
15
+
16
+ require "active_support/core_ext/uri"
17
+ require "active_resource/connection"
18
+ require "active_resource/formats"
19
+ require "active_resource/schema"
20
+ require "active_resource/log_subscriber"
21
+ require "active_resource/associations"
22
+ require "active_resource/reflection"
23
+ require "active_resource/threadsafe_attributes"
24
+
25
+ require "active_model/serializers/xml"
24
26
 
25
27
  module ActiveResource
26
28
  # ActiveResource::Base is the main class for mapping RESTful resources as models in a Rails application.
@@ -300,7 +302,12 @@ module ActiveResource
300
302
  ##
301
303
  # :singleton-method:
302
304
  # The logger for diagnosing and tracing Active Resource calls.
303
- cattr_accessor :logger
305
+ cattr_reader :logger
306
+
307
+ def self.logger=(logger)
308
+ self._connection = nil
309
+ @@logger = logger
310
+ end
304
311
 
305
312
  class_attribute :_format
306
313
  class_attribute :_collection_parser
@@ -378,7 +385,7 @@ module ActiveResource
378
385
  @schema ||= {}.with_indifferent_access
379
386
  @known_attributes ||= []
380
387
 
381
- schema_definition.attrs.each do |k,v|
388
+ schema_definition.attrs.each do |k, v|
382
389
  @schema[k] = v
383
390
  @known_attributes << k
384
391
  end
@@ -417,7 +424,7 @@ module ActiveResource
417
424
  raise ArgumentError, "Expected a hash" unless the_schema.kind_of? Hash
418
425
 
419
426
  schema do
420
- the_schema.each {|k,v| attribute(k,v) }
427
+ the_schema.each { |k, v| attribute(k, v) }
421
428
  end
422
429
  end
423
430
 
@@ -619,7 +626,7 @@ module ActiveResource
619
626
  # * <tt>:ssl_timeout</tt> -The SSL timeout in seconds.
620
627
  def ssl_options=(options)
621
628
  self._connection = nil
622
- @ssl_options = options
629
+ @ssl_options = options
623
630
  end
624
631
 
625
632
  # Returns the SSL options hash.
@@ -636,7 +643,9 @@ module ActiveResource
636
643
  # or not (defaults to <tt>false</tt>).
637
644
  def connection(refresh = false)
638
645
  if _connection_defined? || superclass == Object
639
- self._connection = connection_class.new(site, format) if refresh || _connection.nil?
646
+ self._connection = connection_class.new(
647
+ site, format, logger: logger
648
+ ) if refresh || _connection.nil?
640
649
  _connection.proxy = proxy if proxy
641
650
  _connection.user = user if user
642
651
  _connection.password = password if password
@@ -682,15 +691,15 @@ module ActiveResource
682
691
  return primary_key if primary_key.is_a?(Symbol)
683
692
  primary_key.dup.freeze
684
693
  else
685
- 'id'
694
+ "id"
686
695
  end
687
696
  end
688
697
 
689
698
  # Gets the \prefix for a resource's nested URL (e.g., <tt>prefix/collectionname/1.json</tt>)
690
699
  # This method is regenerated at runtime based on what the \prefix is set to.
691
- def prefix(options={})
700
+ def prefix(options = {})
692
701
  default = site.path
693
- default << '/' unless default[-1..-1] == '/'
702
+ default << "/" unless default[-1..-1] == "/"
694
703
  # generate the actual method based on the current site path
695
704
  self.prefix = default
696
705
  prefix(options)
@@ -705,7 +714,7 @@ module ActiveResource
705
714
 
706
715
  # Sets the \prefix for a resource's nested URL (e.g., <tt>prefix/collectionname/1.json</tt>).
707
716
  # Default value is <tt>site.path</tt>.
708
- def prefix=(value = '/')
717
+ def prefix=(value = "/")
709
718
  # Replace :placeholders with '#{embedded options[:lookups]}'
710
719
  prefix_call = value.gsub(/:\w+/) { |key| "\#{URI.parser.escape options[#{key}].to_s}" }
711
720
 
@@ -763,7 +772,37 @@ module ActiveResource
763
772
  check_prefix_options(prefix_options)
764
773
 
765
774
  prefix_options, query_options = split_options(prefix_options) if query_options.nil?
766
- "#{prefix(prefix_options)}#{collection_name}/#{URI.parser.escape id.to_s}#{format_extension}#{query_string(query_options)}"
775
+ "#{prefix(prefix_options)}#{collection_name}/#{URI.encode_www_form_component(id.to_s)}#{format_extension}#{query_string(query_options)}"
776
+ end
777
+
778
+ # Gets the element url for the given ID in +id+. If the +query_options+ parameter is omitted, Rails
779
+ # will split from the \prefix options.
780
+ #
781
+ # ==== Options
782
+ # +prefix_options+ - A \hash to add a \prefix to the request for nested URLs (e.g., <tt>:account_id => 19</tt>
783
+ # would yield a URL like <tt>https://37s.sunrise.com/accounts/19/purchases.json</tt>).
784
+ #
785
+ # +query_options+ - A \hash to add items to the query string for the request.
786
+ #
787
+ # ==== Examples
788
+ # Post.element_url(1)
789
+ # # => https://37s.sunrise.com/posts/1.json
790
+ #
791
+ # class Comment < ActiveResource::Base
792
+ # self.site = "https://37s.sunrise.com/posts/:post_id"
793
+ # end
794
+ #
795
+ # Comment.element_url(1, :post_id => 5)
796
+ # # => https://37s.sunrise.com/posts/5/comments/1.json
797
+ #
798
+ # Comment.element_url(1, :post_id => 5, :active => 1)
799
+ # # => https://37s.sunrise.com/posts/5/comments/1.json?active=1
800
+ #
801
+ # Comment.element_url(1, {:post_id => 5}, {:active => 1})
802
+ # # => https://37s.sunrise.com/posts/5/comments/1.json?active=1
803
+ #
804
+ def element_url(id, prefix_options = {}, query_options = nil)
805
+ URI.join(site, element_path(id, prefix_options, query_options)).to_s
767
806
  end
768
807
 
769
808
  # Gets the new element path for REST resources.
@@ -931,11 +970,18 @@ module ActiveResource
931
970
  options = arguments.slice!(0) || {}
932
971
 
933
972
  case scope
934
- when :all then find_every(options)
935
- when :first then find_every(options).to_a.first
936
- when :last then find_every(options).to_a.last
937
- when :one then find_one(options)
938
- else find_single(scope, options)
973
+ when :all
974
+ find_every(options)
975
+ when :first
976
+ collection = find_every(options)
977
+ collection && collection.first
978
+ when :last
979
+ collection = find_every(options)
980
+ collection && collection.last
981
+ when :one
982
+ find_one(options)
983
+ else
984
+ find_single(scope, options)
939
985
  end
940
986
  end
941
987
 
@@ -962,7 +1008,7 @@ module ActiveResource
962
1008
 
963
1009
  def where(clauses = {})
964
1010
  raise ArgumentError, "expected a clauses Hash, got #{clauses.inspect}" unless clauses.is_a? Hash
965
- find(:all, :params => clauses)
1011
+ find(:all, params: clauses)
966
1012
  end
967
1013
 
968
1014
 
@@ -996,7 +1042,7 @@ module ActiveResource
996
1042
  prefix_options, query_options = split_options(options[:params])
997
1043
  path = element_path(id, prefix_options, query_options)
998
1044
  response = connection.head(path, headers)
999
- (200..206).include? response.code
1045
+ (200..206).include? response.code.to_i
1000
1046
  end
1001
1047
  # id && !find_single(id, options).nil?
1002
1048
  rescue ActiveResource::ResourceNotFound, ActiveResource::ResourceGone
@@ -1024,7 +1070,7 @@ module ActiveResource
1024
1070
  else
1025
1071
  prefix_options, query_options = split_options(options[:params])
1026
1072
  path = collection_path(prefix_options, query_options)
1027
- instantiate_collection( (format.decode(connection.get(path, headers).body) || []), query_options, prefix_options )
1073
+ instantiate_collection((format.decode(connection.get(path, headers).body) || []), query_options, prefix_options)
1028
1074
  end
1029
1075
  rescue ActiveResource::ResourceNotFound
1030
1076
  # Swallowing ResourceNotFound exceptions and return nil - as per
@@ -1091,8 +1137,8 @@ module ActiveResource
1091
1137
  prefix_options, query_options = {}, {}
1092
1138
 
1093
1139
  (options || {}).each do |key, value|
1094
- next if key.blank? || !key.respond_to?(:to_sym)
1095
- (prefix_parameters.include?(key.to_sym) ? prefix_options : query_options)[key.to_sym] = value
1140
+ next if key.blank?
1141
+ (prefix_parameters.include?(key.to_s.to_sym) ? prefix_options : query_options)[key.to_s.to_sym] = value
1096
1142
  end
1097
1143
 
1098
1144
  [ prefix_options, query_options ]
@@ -1157,13 +1203,13 @@ module ActiveResource
1157
1203
  # not_ryan.hash # => {:not => "an ARes instance"}
1158
1204
  def clone
1159
1205
  # Clone all attributes except the pk and any nested ARes
1160
- cloned = Hash[attributes.reject {|k,v| k == self.class.primary_key || v.is_a?(ActiveResource::Base)}.map { |k, v| [k, v.clone] }]
1206
+ cloned = Hash[attributes.reject { |k, v| k == self.class.primary_key || v.is_a?(ActiveResource::Base) }.map { |k, v| [k, v.clone] }]
1161
1207
  # Form the new resource - bypass initialize of resource with 'new' as that will call 'load' which
1162
1208
  # attempts to convert hashes into member objects and arrays into collections of objects. We want
1163
1209
  # the raw objects to be cloned so we bypass load by directly setting the attributes hash.
1164
1210
  resource = self.class.new({})
1165
1211
  resource.prefix_options = self.prefix_options
1166
- resource.send :instance_variable_set, '@attributes', cloned
1212
+ resource.send :instance_variable_set, "@attributes", cloned
1167
1213
  resource
1168
1214
  end
1169
1215
 
@@ -1338,13 +1384,13 @@ module ActiveResource
1338
1384
  # Person.delete(guys_id)
1339
1385
  # that_guy.exists? # => false
1340
1386
  def exists?
1341
- !new? && self.class.exists?(to_param, :params => prefix_options)
1387
+ !new? && self.class.exists?(to_param, params: prefix_options)
1342
1388
  end
1343
1389
 
1344
1390
  # Returns the serialized string representation of the resource in the configured
1345
1391
  # serialization format specified in ActiveResource::Base.format. The options
1346
1392
  # applicable depend on the configured encoding format.
1347
- def encode(options={})
1393
+ def encode(options = {})
1348
1394
  send("to_#{self.class.format.extension}", options)
1349
1395
  end
1350
1396
 
@@ -1360,7 +1406,7 @@ module ActiveResource
1360
1406
  # my_branch.reload
1361
1407
  # my_branch.name # => "Wilson Road"
1362
1408
  def reload
1363
- self.load(self.class.find(to_param, :params => @prefix_options).attributes, false, true)
1409
+ self.load(self.class.find(to_param, params: @prefix_options).attributes, false, true)
1364
1410
  end
1365
1411
 
1366
1412
  # A method to manually load attributes from a \hash. Recursively loads collections of
@@ -1401,21 +1447,21 @@ module ActiveResource
1401
1447
  attributes.each do |key, value|
1402
1448
  @attributes[key.to_s] =
1403
1449
  case value
1404
- when Array
1405
- resource = nil
1406
- value.map do |attrs|
1407
- if attrs.is_a?(Hash)
1408
- resource ||= find_or_create_resource_for_collection(key)
1409
- resource.new(attrs, persisted)
1410
- else
1411
- attrs.duplicable? ? attrs.dup : attrs
1412
- end
1450
+ when Array
1451
+ resource = nil
1452
+ value.map do |attrs|
1453
+ if attrs.is_a?(Hash)
1454
+ resource ||= find_or_create_resource_for_collection(key)
1455
+ resource.new(attrs, persisted)
1456
+ else
1457
+ attrs.duplicable? ? attrs.dup : attrs
1413
1458
  end
1414
- when Hash
1415
- resource = find_or_create_resource_for(key)
1416
- resource.new(value, persisted)
1417
- else
1418
- value.duplicable? ? value.dup : value
1459
+ end
1460
+ when Hash
1461
+ resource = find_or_create_resource_for(key)
1462
+ resource.new(value, persisted)
1463
+ else
1464
+ value.duplicable? ? value.dup : value
1419
1465
  end
1420
1466
  end
1421
1467
  self
@@ -1472,12 +1518,20 @@ module ActiveResource
1472
1518
  end
1473
1519
  end
1474
1520
 
1475
- def to_json(options={})
1476
- super(include_root_in_json ? { :root => self.class.element_name }.merge(options) : options)
1521
+ def to_json(options = {})
1522
+ super(include_root_in_json ? { root: self.class.element_name }.merge(options) : options)
1477
1523
  end
1478
1524
 
1479
- def to_xml(options={})
1480
- super({ :root => self.class.element_name }.merge(options))
1525
+ def to_xml(options = {})
1526
+ super({ root: self.class.element_name }.merge(options))
1527
+ end
1528
+
1529
+ def read_attribute_for_serialization(n)
1530
+ if !attributes[n].nil?
1531
+ attributes[n]
1532
+ elsif respond_to?(n)
1533
+ send(n)
1534
+ end
1481
1535
  end
1482
1536
 
1483
1537
  protected
@@ -1505,9 +1559,9 @@ module ActiveResource
1505
1559
  end
1506
1560
 
1507
1561
  def load_attributes_from_response(response)
1508
- if (response_code_allows_body?(response.code) &&
1509
- (response['Content-Length'].nil? || response['Content-Length'] != "0") &&
1510
- !response.body.nil? && response.body.strip.size > 0)
1562
+ if response_code_allows_body?(response.code.to_i) &&
1563
+ (response["Content-Length"].nil? || response["Content-Length"] != "0") &&
1564
+ !response.body.nil? && response.body.strip.size > 0
1511
1565
  load(self.class.format.decode(response.body), true, true)
1512
1566
  @persisted = true
1513
1567
  end
@@ -1515,13 +1569,17 @@ module ActiveResource
1515
1569
 
1516
1570
  # Takes a response from a typical create post and pulls the ID out
1517
1571
  def id_from_response(response)
1518
- response['Location'][/\/([^\/]*?)(\.\w+)?$/, 1] if response['Location']
1572
+ response["Location"][/\/([^\/]*?)(\.\w+)?$/, 1] if response["Location"]
1519
1573
  end
1520
1574
 
1521
1575
  def element_path(options = nil)
1522
1576
  self.class.element_path(to_param, options || prefix_options)
1523
1577
  end
1524
1578
 
1579
+ def element_url(options = nil)
1580
+ self.class.element_url(to_param, options || prefix_options)
1581
+ end
1582
+
1525
1583
  def new_element_path
1526
1584
  self.class.new_element_path(prefix_options)
1527
1585
  end
@@ -1532,13 +1590,9 @@ module ActiveResource
1532
1590
 
1533
1591
  private
1534
1592
 
1535
- def read_attribute_for_serialization(n)
1536
- attributes[n]
1537
- end
1538
-
1539
1593
  # Determine whether the response is allowed to have a body per HTTP 1.1 spec section 4.4.1
1540
1594
  def response_code_allows_body?(c)
1541
- !((100..199).include?(c) || [204,304].include?(c))
1595
+ !((100..199).include?(c) || [204, 304].include?(c))
1542
1596
  end
1543
1597
 
1544
1598
  # Tries to find a resource for a given collection name; if it fails, then the resource is created
@@ -1551,7 +1605,7 @@ module ActiveResource
1551
1605
  # if it fails, then the resource is created
1552
1606
  def find_or_create_resource_in_modules(resource_name, module_names)
1553
1607
  receiver = Object
1554
- namespaces = module_names[0, module_names.size-1].map do |module_name|
1608
+ namespaces = module_names[0, module_names.size - 1].map do |module_name|
1555
1609
  receiver = receiver.const_get(module_name)
1556
1610
  end
1557
1611
  const_args = [resource_name, false]
@@ -1568,7 +1622,11 @@ module ActiveResource
1568
1622
  resource_name = name.to_s.camelize
1569
1623
 
1570
1624
  const_args = [resource_name, false]
1571
- if self.class.const_defined?(*const_args)
1625
+
1626
+ if !const_valid?(*const_args)
1627
+ # resource_name is not a valid ruby module name and cannot be created normally
1628
+ find_or_create_resource_for(:UnnamedResource)
1629
+ elsif self.class.const_defined?(*const_args)
1572
1630
  self.class.const_get(*const_args)
1573
1631
  else
1574
1632
  ancestors = self.class.name.to_s.split("::")
@@ -1584,6 +1642,13 @@ module ActiveResource
1584
1642
  end
1585
1643
  end
1586
1644
 
1645
+ def const_valid?(*const_args)
1646
+ self.class.const_defined?(*const_args)
1647
+ true
1648
+ rescue NameError
1649
+ false
1650
+ end
1651
+
1587
1652
  # Create and return a class definition for a resource inside the current resource
1588
1653
  def create_resource_for(resource_name)
1589
1654
  resource = self.class.const_set(resource_name, Class.new(ActiveResource::Base))
@@ -1,4 +1,6 @@
1
- require 'active_support/core_ext/array/wrap'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/array/wrap"
2
4
 
3
5
  module ActiveResource
4
6
  module Callbacks
@@ -1,11 +1,13 @@
1
- require 'active_support/core_ext/module/delegation'
2
- require 'active_support/inflector'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/module/delegation"
4
+ require "active_support/inflector"
3
5
 
4
6
  module ActiveResource # :nodoc:
5
7
  class Collection # :nodoc:
6
8
  SELF_DEFINE_METHODS = [:to_a, :collect!, :map!]
7
9
  include Enumerable
8
- delegate :to_yaml, :all?, *(Array.instance_methods(false) - SELF_DEFINE_METHODS), :to => :to_a
10
+ delegate :to_yaml, :all?, *(Array.instance_methods(false) - SELF_DEFINE_METHODS), to: :to_a
9
11
 
10
12
  # The array of actual elements returned by index actions
11
13
  attr_accessor :elements, :resource_class, :original_params