As described in #481, adding a protected field like `legal_entity` as
part of an update API operation can cause some issues like a custom
encoding scheme not being considered and special handling around empty
values being ignored.
As a an easy fix for this, let's disallow access to protected fields in
the same way that we disallow them from being set directly on an
instance of a given model.
Helps address (but is not a complete fix for) #481.
* Rename the `Update` operation to `Save`
* Add the `update` class method to all saveable resources
* Add tests for update method
* Add tests for plans, invoice items, and application fees
I'm not sure exactly what changed here (did we change the `$VERBOSE`
setting?), but I'm not seeing a whole lot of warnings when running the
test suites locally and in CI. For example:
```
Started
........................................./home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
............../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
......../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
.../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
........./home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
...
..../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
....../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
..../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
......./home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
........./home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
........../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
................./home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
.../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
..../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
....../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
..........
........./home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
....../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
......../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
......../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
............./home/travis/build/stripe/stripe-ruby/lib/stripe/stripe_object.rb:35: warning: instance variable @values not initialized
./home/travis/build/stripe/stripe-ruby/lib/stripe/stripe_object.rb:35: warning: instance variable @values not initialized
...................../home/travis/build/stripe/stripe-ruby/lib/stripe/transfer.rb:8: warning: instance variable @api_key not initialized
..............
..
Finished in 0.785621037 seconds.
```
Most of these are due to unused or uninitialized variables. This patch
fixes all warnings by fixing offending code.
This pull does two major things:
1. Refactors `serialize_params` to be more concise and readable while
still complying to our existing test suite. Unfortunately over time
this method has become a ball of mud that's very difficult to reason
about, as recently evidenced by #384.
2. Moves `serialize_params` from class method to instance method (while
still keeping for old class method for backwards compatibility). This
is to give it a more sane interface.
When additional filters were provided for pagination like an expansion
or a predicate, they would not propagate to any call after the first.
This patch addresses that issue by storing all filters and moving them
to any new page objects being created.
Fixes#331.
This dials down the safety of `StripeObject`'s `#update_attributes`
method so that it allows properties to be assigned that it doesn't yet
know about. We're doing this for a few reasons:
1. To reflect the current behavior of accessors (i.e. `obj.name = ...`)
through `method_missing`.
2. To allow `#update_attributes` to assign properties on new projects
that don't yet know their schema from an API call.
Fixes#324.
As discussed in #325, this deprecates the public visibility of
`#refresh_from` (by renaming it). It also adds some deprecation
infrastructure to produce warnings when it's used.
Lets not be too shy about just using `extend` instead of `include` here
when it's more appropriate to do so. The advantage to this approach is
that the module can be either extended _or_ included with this change,
but couldn't be without it due to the `ClassMethods` meta-magic.
List has already started doing this as of #314, so we don't have to be
afraid of breaking convention here.
Usage on a top-level collection:
```
Stripe::Customer.list.auto_paging_each do |customer|
puts customer
end
```
Usage on a subcollection:
``` ruby
customer.invoices.auto_paging_each do |invoice|
puts invoice
end
```
We've also renamed `#all` to `#list` to prevent confusion ("all" implies
that all resources are being returned, and in Stripe's paginated API
this was not the case). An alias has been provided for backward API
compatibility.
Fixes#167.
Replaces #211 and #248.
As detailed in issue #119, we've somewhat unfortunately been allowing
object attributes to be passed in during a #save because we mix any
arguments directly into the serialized hash (it seems that this was
originally intended to be used more for meta parameters that go to the
request).
As also noted in #119, this use causes problems when certain types of
parameters (like subobjects) are used. We're now left in the somewhat
awkward position of either:
1. Removing this functionality on #save and breaking what may be
behavior that people depend on.
2. Fully support this mass assignment.
This patch takes the second path by extracting a new #update_attributes
method and using it from #save. It's still far from a perfect approach
because keys that have the same name as certain options (e.g. `req_url`)
are not going to work, but it should capture the behavior that most
people want.
Fixes#119.
Modifies the behavior of an update so that it can create an object if it
was new. This allows an "upsert"-like functionality where the SDK will
tend to do the right/expected thing.
This is a tad janky in that it checks for the existence of a class-level
`.create` method which is expected to come from a different module, but
most modules in the project are already fairly deeply intertwined and
co-dependent.
Fixes#165.
Rationale:
Sometime you don't care about the current state of a resource
you just want to update one of it's attributes.
It should only require one request.
fixes#52
```ruby
c = Stripe::Customer.new("cus_1EqKjPaFs4ZwDD")
c.description = 'Ny new Description'
c.save
```
Before:
```json
{
error: {
type: "invalid_request_error",
message: "A parameter provided in the URL (id) was repeated as a GET or POST parameter. You can only provide this information as a portion of the URL.",
param: "id",
}
}
```
After:
Successfully update the customer and return it's whole state.