mirror of
https://github.com/stripe/stripe-ruby.git
synced 2025-10-09 00:03:05 -04:00
Adds the magic `frozen_string_literal: true` comment to every file and enables a Rubocop rule to make sure that it's always going to be there going forward as well. See here for more background [1], but the basic idea is that unlike many other languages, static strings in code are mutable by default. This has since been acknowledged as not a particularly good idea, and the intention is to rectify the mistake when Ruby 3 comes out, where all string literals will be frozen. The `frozen_string_literal` magic comment was introduced in Ruby 2.3 as a way of easing the transition, and allows libraries and projects to freeze their literals in advance. I don't think this is breaking in any way: it's possible that users might've been pulling out one of are literals somehow and mutating it, but that would probably not have been useful for anything and would certainly not be recommended, so I'm quite comfortable pushing this change through as a minor version. As discussed in #641. [1] https://stackoverflow.com/a/37799399
97 lines
3.7 KiB
Ruby
97 lines
3.7 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Stripe
|
|
module APIOperations
|
|
module Save
|
|
module ClassMethods
|
|
# Updates an API resource
|
|
#
|
|
# Updates the identified resource with the passed in parameters.
|
|
#
|
|
# ==== Attributes
|
|
#
|
|
# * +id+ - ID of the resource to update.
|
|
# * +params+ - A hash of parameters to pass to the API
|
|
# * +opts+ - A Hash of additional options (separate from the params /
|
|
# object values) to be added to the request. E.g. to allow for an
|
|
# idempotency_key to be passed in the request headers, or for the
|
|
# api_key to be overwritten. See {APIOperations::Request.request}.
|
|
def update(id, params = {}, opts = {})
|
|
params.each_key do |k|
|
|
if protected_fields.include?(k)
|
|
raise ArgumentError, "Cannot update protected field: #{k}"
|
|
end
|
|
end
|
|
|
|
resp, opts = request(:post, "#{resource_url}/#{id}", params, opts)
|
|
Util.convert_to_stripe_object(resp.data, opts)
|
|
end
|
|
end
|
|
|
|
# Creates or updates an API resource.
|
|
#
|
|
# If the resource doesn't yet have an assigned ID and the resource is one
|
|
# that can be created, then the method attempts to create the resource.
|
|
# The resource is updated otherwise.
|
|
#
|
|
# ==== Attributes
|
|
#
|
|
# * +params+ - Overrides any parameters in the resource's serialized data
|
|
# and includes them in the create or update. If +:req_url:+ is included
|
|
# in the list, it overrides the update URL used for the create or
|
|
# update.
|
|
# * +opts+ - A Hash of additional options (separate from the params /
|
|
# object values) to be added to the request. E.g. to allow for an
|
|
# idempotency_key to be passed in the request headers, or for the
|
|
# api_key to be overwritten. See {APIOperations::Request.request}.
|
|
def save(params = {}, opts = {})
|
|
# We started unintentionally (sort of) allowing attributes sent to
|
|
# +save+ to override values used during the update. So as not to break
|
|
# the API, this makes that official here.
|
|
update_attributes(params)
|
|
|
|
# Now remove any parameters that look like object attributes.
|
|
params = params.reject { |k, _| respond_to?(k) }
|
|
|
|
values = serialize_params(self).merge(params)
|
|
|
|
# note that id gets removed here our call to #url above has already
|
|
# generated a uri for this object with an identifier baked in
|
|
values.delete(:id)
|
|
|
|
resp, opts = request(:post, save_url, values, opts)
|
|
initialize_from(resp.data, opts)
|
|
end
|
|
|
|
def self.included(base)
|
|
# Set `metadata` as additive so that when it's set directly we remember
|
|
# to clear keys that may have been previously set by sending empty
|
|
# values for them.
|
|
#
|
|
# It's possible that not every object with `Save` has `metadata`, but
|
|
# it's a close enough heuristic, and having this option set when there
|
|
# is no `metadata` field is not harmful.
|
|
base.additive_object_param(:metadata)
|
|
|
|
base.extend(ClassMethods)
|
|
end
|
|
|
|
private
|
|
|
|
def save_url
|
|
# This switch essentially allows us "upsert"-like functionality. If the
|
|
# API resource doesn't have an ID set (suggesting that it's new) and
|
|
# its class responds to .create (which comes from
|
|
# Stripe::APIOperations::Create), then use the URL to create a new
|
|
# resource. Otherwise, generate a URL based on the object's identifier
|
|
# for a normal update.
|
|
if self[:id].nil? && self.class.respond_to?(:create)
|
|
self.class.resource_url
|
|
else
|
|
resource_url
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|