Class: Recurly::Resource
- Inherits:
-
Object
- Object
- Recurly::Resource
- Defined in:
- lib/recurly/resource.rb,
lib/recurly/resource/pager.rb
Overview
The base class for all Recurly resources (e.g. Account, Subscription, Transaction).
Resources behave much like ActiveModel classes, especially like ActiveRecord.
Life Cycle
To take you through the typical life cycle of a resource, we’ll use Account as an example.
Creating a Record
You can instantiate a record before attempting to save it.
account = Recurly::Account.new :first_name => 'Walter'
Once instantiated, you can assign and reassign any attribute.
account.first_name = 'Walt'
account.last_name = 'White'
When you’re ready to save, do so.
account.save # => false
If save returns false
, validation likely failed. You can check the record for errors.
account.errors # => {"account_code"=>["can't be blank"]}
Once the errors are fixed, you can try again.
account.account_code = 'heisenberg'
account.save # => true
The object will be updated with any information provided by the server (including any UUIDs set).
account.created_at # => 2011-04-30 07:13:35 -0700
You can also create accounts in one fell swoop.
Recurly::Account.create(
:first_name => 'Jesse'
:last_name => 'Pinkman'
:account_code => 'capn_cook'
)
# => #<Recurly::Account account_code: "capn_cook" ...>
You can use alternative “bang” methods for exception control. If the record fails to save, a Recurly::Resource::Invalid exception will be raised.
begin
account = Recurly::Account.new :first_name => 'Junior'
account.save!
rescue Recurly::Resource::Invalid
p account.errors
end
You can access the invalid record from the exception itself (if, for example, you use the create!
method).
begin
Recurly::Account.create! :first_name => 'Skylar', :last_name => 'White'
rescue Recurly::Resource::Invalid => e
p e.record.errors
end
Fetching a Record
Records are fetched by their unique identifiers.
account = Recurly::Account.find 'better_call_saul'
# => #<Recurly::Account account_code: "better_call_saul" ...>
If the record doesn’t exist, a Recurly::Resource::NotFound exception will be raised.
Updating a Record
Once fetched, a record can be updated with a hash of attributes.
account.update_attributes :first_name => 'Saul', :last_name => 'Goodman'
# => true
(A bang method, update_attributes!, will raise Recurly::Resource::Invalid.)
You can also update a record by setting attributes and calling save.
account.last_name = 'McGill'
account.save # Alternatively, call save!
Deleting a Record
To delete (deactivate, close, etc.) a fetched record, merely call destroy on it.
account.destroy # => true
Fetching a List of Records
If you want to iterate over a list of accounts, you can use a Pager.
pager = Account.paginate :per_page => 50
If you want to iterate over every record, a convenience method will automatically paginate:
Account.find_each { |account| p account }
Direct Known Subclasses
Account, AddOn, Adjustment, BillingInfo, Coupon, Invoice, Plan, Redemption, Subscription, Transaction
Defined Under Namespace
Classes: Invalid, NotFound, Pager
Class Attribute Summary collapse
-
.attribute_names ⇒ Array?
readonly
The list of attribute names defined for the resource class.
Instance Attribute Summary collapse
-
#attributes ⇒ Hash
The raw hash of record attributes.
-
#etag ⇒ String?
readonly
An ETag for the current record.
- #response ⇒ Net::HTTPResponse? readonly
-
#uri ⇒ String?
The unique resource identifier (URI) of the record (if persisted).
Class Method Summary collapse
- .all(options = {}) ⇒ Object
-
.associations ⇒ Hash
A list of association names for the current class.
-
.belongs_to(parent_name, options = {}) ⇒ Proc
Establishes a belongs_to association.
-
.collection_name ⇒ String
(also: collection_path)
The underscored, pluralized name of the resource class.
-
.count ⇒ Integer
The total record count of the resource in question.
-
.create(attributes = {}) ⇒ Resource
Instantiates and attempts to save a record.
-
.create!(attributes = {}) ⇒ Resource
Instantiates and attempts to save a record.
-
.define_attribute_methods(attribute_names) ⇒ Array
Per attribute, defines readers, writers, boolean and change-tracking methods.
- .embedded!(root_index = false) ⇒ Object
-
.find(uuid, options = {}) ⇒ Resource
A record matching the designated unique identifier.
-
.find_each(per_page = 50) {|record| ... } ⇒ nil
Iterates through every record by automatically paging.
- .first ⇒ Resource?
-
.from_response(response) ⇒ Resource
Instantiates a record from an HTTP response, setting the record’s response attribute in the process.
-
.from_xml(xml) ⇒ Resource
Instantiates a record from an XML blob: either a String or XML element.
-
.has_many(collection_name, options = {}) ⇒ Proc?
Establishes a has_many association.
-
.has_one(member_name, options = {}) ⇒ Proc?
Establishes a has_one association.
-
.member_name ⇒ String
The underscored name of the resource class.
-
.member_path(uuid) ⇒ String
The relative path to a resource’s identifier from the API’s base URI.
-
.paginate(options = {}) ⇒ Pager
(also: scoped, where)
A pager with an iterable collection of records.
-
.reflect_on_association(name) ⇒ :has_many, ...
An association type.
-
.resource_name ⇒ String
The demodulized name of the resource class.
-
.scope(name, params = {}) ⇒ Proc
Defines a new resource scope.
-
.scopes ⇒ Hash
Defined scopes per resource.
Instance Method Summary collapse
- #==(other) ⇒ Object
-
#changed ⇒ Array
A list of changed attribute keys.
-
#changed? ⇒ true, false
Do any attributes have unsaved changes?.
-
#changed_attributes ⇒ Hash
Hash of changed attributes.
-
#changes ⇒ Hash
Map of changed attributes to original value and new value.
-
#destroy ⇒ true, false
Attempts to destroy the record.
-
#destroyed? ⇒ true, false
Has the record been destroyed? (Set
true
after a successful destroy.). -
#errors ⇒ Hash
A hash with indifferent read access containing any validation errors where the key is the attribute name and the value is an array of error messages.
-
#initialize(attributes = {}) {|_self| ... } ⇒ Resource
constructor
A new resource instance.
- #inspect(attributes = self.class.attribute_names.to_a) ⇒ String (also: #to_s)
- #marshal_dump ⇒ Object
- #marshal_load(serialization) ⇒ Object
-
#new_record? ⇒ true, false
Is the record new (i.e., not saved on Recurly’s servers)?.
-
#persist!(saved = false) ⇒ true
Marks a record as persisted, i.e.
-
#persisted? ⇒ true, false
Has the record persisted (i.e., saved on Recurly’s servers)?.
-
#previous_changes ⇒ Hash
Previously-changed attributes.
-
#read_attribute(key) ⇒ Object
(also: #[])
The value of a specified attribute, lazily fetching any defined association.
-
#reload(response = nil) ⇒ self
Reloads the record from the server.
-
#save ⇒ true, false
Attempts to save the record, returning the success of the request.
-
#save! ⇒ true
Attempts to save the record, returning
true
if the record was saved and raising Invalid otherwise. - #signable_attributes ⇒ Object
- #to_param ⇒ Object
-
#to_xml(options = {}) ⇒ String
Serializes the record to XML.
-
#update_attributes(attributes = {}) ⇒ true, false
Update a record with a given hash of attributes.
-
#update_attributes!(attributes = {}) ⇒ true
Update a record with a given hash of attributes.
-
#valid? ⇒ true, ...
The validity of the record:
true
if the record was successfully saved (or persisted and unchanged),false
if the record was not successfully saved, ornil
for a record with an unknown state (i.e. (i.e. new records that haven’t been saved and persisted records with changed attributes).. -
#write_attribute(key, value) ⇒ Object
(also: #[]=)
Sets the value of a specified attribute.
Constructor Details
#initialize(attributes = {}) {|_self| ... } ⇒ Resource
Returns A new resource instance.
538 539 540 541 542 543 544 545 546 547 |
# File 'lib/recurly/resource.rb', line 538 def initialize attributes = {} if instance_of? Resource raise Error, "#{self.class} is an abstract class and cannot be instantiated" end @attributes, @new_record, @destroyed, @uri, @href = {}, true, false self.attributes = attributes yield self if block_given? end |
Class Attribute Details
.attribute_names ⇒ Array? (readonly)
Returns The list of attribute names defined for the resource class.
229 230 231 |
# File 'lib/recurly/resource.rb', line 229 def attribute_names @attribute_names end |
Instance Attribute Details
#attributes ⇒ Hash
Returns The raw hash of record attributes.
524 525 526 |
# File 'lib/recurly/resource.rb', line 524 def attributes @attributes end |
#etag ⇒ String? (readonly)
Returns An ETag for the current record.
531 532 533 |
# File 'lib/recurly/resource.rb', line 531 def etag @etag end |
#response ⇒ Net::HTTPResponse? (readonly)
528 529 530 |
# File 'lib/recurly/resource.rb', line 528 def response @response end |
Class Method Details
.all(options = {}) ⇒ Object
250 251 252 |
# File 'lib/recurly/resource.rb', line 250 def all = {} paginate().to_a end |
.associations ⇒ Hash
Returns A list of association names for the current class.
428 429 430 431 432 433 434 435 436 |
# File 'lib/recurly/resource.rb', line 428 def associations @associations ||= begin unless constants.include? :Associations include const_set :Associations, Module.new end { :has_many => [], :has_one => [], :belongs_to => [] } end end |
.belongs_to(parent_name, options = {}) ⇒ Proc
Establishes a belongs_to association.
497 498 499 500 501 502 503 504 505 506 507 |
# File 'lib/recurly/resource.rb', line 497 def belongs_to parent_name, = {} associations[:belongs_to] << parent_name.to_s self::Associations.module_eval { define_method(parent_name) { self[parent_name] } if .key?(:readonly) && [:readonly] == false define_method("#{parent_name}=") { |parent| self[parent_name] = parent } end } end |
.collection_name ⇒ String Also known as: collection_path
Returns The underscored, pluralized name of the resource class.
167 168 169 |
# File 'lib/recurly/resource.rb', line 167 def collection_name Helper.pluralize Helper.underscore(resource_name) end |
.count ⇒ Integer
Returns The total record count of the resource in question.
286 287 288 |
# File 'lib/recurly/resource.rb', line 286 def count paginate.count end |
.create(attributes = {}) ⇒ Resource
Instantiates and attempts to save a record.
330 331 332 |
# File 'lib/recurly/resource.rb', line 330 def create attributes = {} new(attributes) { |record| record.save } end |
.create!(attributes = {}) ⇒ Resource
Instantiates and attempts to save a record.
340 341 342 |
# File 'lib/recurly/resource.rb', line 340 def create! attributes = {} new(attributes) { |record| record.save! } end |
.define_attribute_methods(attribute_names) ⇒ Array
Returns Per attribute, defines readers, writers, boolean and change-tracking methods.
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/recurly/resource.rb', line 206 def define_attribute_methods attribute_names @attribute_names = attribute_names.map! { |m| m.to_s }.sort!.freeze remove_const :AttributeMethods if constants.include? :AttributeMethods include const_set :AttributeMethods, Module.new { attribute_names.each do |name| define_method(name) { self[name] } # Get. define_method("#{name}=") { |value| self[name] = value } # Set. define_method("#{name}?") { !!self[name] } # Present. define_method("#{name}_change") { changes[name] } # Dirt... define_method("#{name}_changed?") { changed_attributes.key? name } define_method("#{name}_was") { changed_attributes[name] } define_method("#{name}_previously_changed?") { previous_changes.key? name } define_method("#{name}_previously_was") { previous_changes[name].first if previous_changes.key? name } end } end |
.embedded!(root_index = false) ⇒ Object
514 515 516 517 518 519 520 |
# File 'lib/recurly/resource.rb', line 514 def root_index = false private :initialize private_class_method(*%w(new create create!)) unless root_index private_class_method(*%w(all find_each first paginate scoped where)) end end |
.find(uuid, options = {}) ⇒ Resource
Returns A record matching the designated unique identifier.
311 312 313 314 315 316 317 318 319 320 321 322 323 |
# File 'lib/recurly/resource.rb', line 311 def find uuid, = {} if uuid.nil? # Should we raise an ArgumentError, instead? raise NotFound, "can't find a record with nil identifier" end uri = uuid =~ /^http/ ? uuid : member_path(uuid) begin from_response API.get(uri, {}, ) rescue API::NotFound => e raise NotFound, e.description end end |
.find_each(per_page = 50) {|record| ... } ⇒ nil
Iterates through every record by automatically paging.
278 279 280 |
# File 'lib/recurly/resource.rb', line 278 def find_each per_page = 50 paginate(:per_page => per_page).find_each(&Proc.new) end |
.first ⇒ Resource?
292 293 294 |
# File 'lib/recurly/resource.rb', line 292 def first paginate(:per_page => 1).first end |
.from_response(response) ⇒ Resource
Instantiates a record from an HTTP response, setting the record’s response attribute in the process.
349 350 351 352 353 354 355 356 357 358 |
# File 'lib/recurly/resource.rb', line 349 def from_response response case response['Content-Type'] when %r{application/pdf} response.body else # when %r{application/xml} record = from_xml response.body record.instance_eval { @etag, @response = response['ETag'], response } record end end |
.from_xml(xml) ⇒ Resource
Instantiates a record from an XML blob: either a String or XML element.
Assuming the record is from an API response, the record is flagged as persisted.
368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 |
# File 'lib/recurly/resource.rb', line 368 def from_xml xml xml = XML.new xml if xml.name == member_name record = new elsif Recurly.const_defined?( class_name = Helper.classify(xml.name), false ) klass = Recurly.const_get class_name, false record = klass.send :new elsif root = xml.root and root.elements.empty? return XML.cast root else record = {} end klass ||= self associations = klass.associations xml.root.attributes.each do |name, value| record.instance_variable_set "@#{name}", value.to_s end xml.each_element do |el| if el.name == 'a' name, uri = el.attribute('name').value, el.attribute('href').value record[name] = case el.attribute('method').to_s when 'get', '' then proc { |*opts| API.get uri, {}, *opts } when 'post' then proc { |*opts| API.post uri, nil, *opts } when 'put' then proc { |*opts| API.put uri, nil, *opts } when 'delete' then proc { |*opts| API.delete uri, *opts } end next end if el.children.empty? && href = el.attribute('href') resource_class = Recurly.const_get( Helper.classify(el.attribute('type') || el.name), false ) record[el.name] = case el.name when *associations[:has_many] Pager.new resource_class, :uri => href.value, :parent => record when *(associations[:has_one] + associations[:belongs_to]) lambda { begin relation = resource_class.from_response API.get(href.value) relation.attributes[member_name] = record relation rescue Recurly::API::NotFound end } end else record[el.name] = XML.cast el end end record.persist! if record.respond_to? :persist! record end |
.has_many(collection_name, options = {}) ⇒ Proc?
Establishes a has_many association.
444 445 446 447 448 449 450 451 452 453 454 455 456 |
# File 'lib/recurly/resource.rb', line 444 def has_many collection_name, = {} associations[:has_many] << collection_name.to_s self::Associations.module_eval { define_method(collection_name) { self[collection_name] ||= [] } if .key?(:readonly) && [:readonly] == false define_method("#{collection_name}=") { |collection| self[collection_name] = collection } end } end |
.has_one(member_name, options = {}) ⇒ Proc?
Establishes a has_one association.
464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 |
# File 'lib/recurly/resource.rb', line 464 def has_one member_name, = {} associations[:has_one] << member_name.to_s self::Associations.module_eval { define_method(member_name) { self[member_name] } if .key?(:readonly) && [:readonly] == false associated = Recurly.const_get Helper.classify(member_name), false define_method("#{member_name}=") { |member| associated_uri = "#{path}/#{member_name}" self[member_name] = case member when Hash associated.send :new, member.merge(:uri => associated_uri) when associated member.uri = associated_uri and member else raise ArgumentError, "expected #{associated}" end } define_method("build_#{member_name}") { |*args| attributes = args.shift || {} self[member_name] = associated.send( :new, attributes.merge(:uri => "#{path}/#{member_name}") ).tap { |child| child.attributes[self.class.member_name] = self } } define_method("create_#{member_name}") { |*args| send("build_#{member_name}", *args).tap { |child| child.save } } end } end |
.member_name ⇒ String
Returns The underscored name of the resource class.
175 176 177 |
# File 'lib/recurly/resource.rb', line 175 def member_name Helper.underscore resource_name end |
.member_path(uuid) ⇒ String
Returns The relative path to a resource’s identifier from the API’s base URI.
185 186 187 |
# File 'lib/recurly/resource.rb', line 185 def member_path uuid [collection_path, uuid].compact.join '/' end |
.paginate(options = {}) ⇒ Pager Also known as: scoped, where
Returns A pager with an iterable collection of records.
244 245 246 |
# File 'lib/recurly/resource.rb', line 244 def paginate = {} Pager.new self, end |
.reflect_on_association(name) ⇒ :has_many, ...
Returns An association type.
510 511 512 |
# File 'lib/recurly/resource.rb', line 510 def reflect_on_association name a = associations.find { |k, v| v.include? name.to_s } and a.first end |
.resource_name ⇒ String
Returns The demodulized name of the resource class.
159 160 161 |
# File 'lib/recurly/resource.rb', line 159 def resource_name Helper.demodulize name end |
.scope(name, params = {}) ⇒ Proc
Defines a new resource scope.
264 265 266 267 268 |
# File 'lib/recurly/resource.rb', line 264 def scope name, params = {} scopes[name = name.to_s] = params extend const_set :Scopes, Module.new unless const_defined? :Scopes self::Scopes.send(:define_method, name) { paginate scopes[name] } end |
.scopes ⇒ Hash
Returns Defined scopes per resource.
255 256 257 |
# File 'lib/recurly/resource.rb', line 255 def scopes @scopes ||= Recurly::Helper.hash_with_indifferent_read_access end |
Instance Method Details
#==(other) ⇒ Object
853 854 855 |
# File 'lib/recurly/resource.rb', line 853 def == other other.is_a?(self.class) && other.to_s == to_s end |
#changed ⇒ Array
Returns A list of changed attribute keys.
577 578 579 |
# File 'lib/recurly/resource.rb', line 577 def changed changed_attributes.keys end |
#changed? ⇒ true, false
Do any attributes have unsaved changes?
583 584 585 |
# File 'lib/recurly/resource.rb', line 583 def changed? !changed_attributes.empty? end |
#changed_attributes ⇒ Hash
Returns Hash of changed attributes.
572 573 574 |
# File 'lib/recurly/resource.rb', line 572 def changed_attributes @changed_attributes ||= {} end |
#changes ⇒ Hash
Returns Map of changed attributes to original value and new value.
588 589 590 591 592 |
# File 'lib/recurly/resource.rb', line 588 def changes changed_attributes.inject({}) { |changes, (key, original_value)| changes[key] = [original_value, self[key]] and changes } end |
#destroy ⇒ true, false
Attempts to destroy the record.
(if the record does not persist on Recurly).
841 842 843 844 845 846 847 |
# File 'lib/recurly/resource.rb', line 841 def destroy return false unless persisted? @response = API.delete uri @destroyed = true rescue API::NotFound => e raise NotFound, e.description end |
#destroyed? ⇒ true, false
Has the record been destroyed? (Set true
after a successful destroy.)
613 614 615 |
# File 'lib/recurly/resource.rb', line 613 def destroyed? @destroyed end |
#errors ⇒ Hash
Returns A hash with indifferent read access containing any validation errors where the key is the attribute name and the value is an array of error messages.
801 802 803 |
# File 'lib/recurly/resource.rb', line 801 def errors @errors ||= Recurly::Helper.hash_with_indifferent_read_access end |
#inspect(attributes = self.class.attribute_names.to_a) ⇒ String Also known as: to_s
884 885 886 887 888 889 890 891 892 |
# File 'lib/recurly/resource.rb', line 884 def inspect attributes = self.class.attribute_names.to_a string = "#<#{self.class}" string << "##@type" if instance_variable_defined? :@type attributes += %w(errors) if errors.any? string << " %s" % attributes.map { |k| "#{k}: #{self.send(k).inspect}" }.join(', ') string << '>' end |
#marshal_dump ⇒ Object
857 858 859 860 861 862 863 864 865 866 867 868 869 |
# File 'lib/recurly/resource.rb', line 857 def marshal_dump [ @attributes.reject { |k, v| v.is_a? Proc }, @new_record, @destroyed, @uri, @href, changed_attributes, previous_changes, etag, response ] end |
#marshal_load(serialization) ⇒ Object
871 872 873 874 875 876 877 878 879 880 881 |
# File 'lib/recurly/resource.rb', line 871 def marshal_load serialization @attributes, @new_record, @destroyed, @uri, @href, @changed_attributes, @previous_changes, @response, @etag = serialization end |
#new_record? ⇒ true, false
Is the record new (i.e., not saved on Recurly’s servers)?
605 606 607 |
# File 'lib/recurly/resource.rb', line 605 def new_record? @new_record end |
#persist!(saved = false) ⇒ true
Marks a record as persisted, i.e. not a new or deleted record, resetting any tracked attribute changes in the process. (This is an internal method and should probably not be called unless you know what you’re doing.)
811 812 813 814 815 816 817 818 |
# File 'lib/recurly/resource.rb', line 811 def persist! saved = false @new_record, @uri = false if changed? @previous_changes = changes if saved changed_attributes.clear end true end |
#persisted? ⇒ true, false
Has the record persisted (i.e., saved on Recurly’s servers)?
622 623 624 |
# File 'lib/recurly/resource.rb', line 622 def persisted? !(new_record? || destroyed?) end |
#previous_changes ⇒ Hash
Returns Previously-changed attributes.
596 597 598 |
# File 'lib/recurly/resource.rb', line 596 def previous_changes @previous_changes ||= {} end |
#read_attribute(key) ⇒ Object Also known as: []
The value of a specified attribute, lazily fetching any defined association.
634 635 636 637 638 639 640 |
# File 'lib/recurly/resource.rb', line 634 def read_attribute key value = attributes[key = key.to_s] if value.respond_to?(:call) && self.class.reflect_on_association(key) value = attributes[key] = value.call end value end |
#reload(response = nil) ⇒ self
Returns Reloads the record from the server.
554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 |
# File 'lib/recurly/resource.rb', line 554 def reload response = nil if response return if response.body.to_s.length.zero? fresh = self.class.from_response response else fresh = self.class.find( @href || to_param, :etag => (etag unless changed?) ) end fresh and copy_from fresh persist! true self rescue API::NotModified self end |
#save ⇒ true, false
Attempts to save the record, returning the success of the request.
717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 |
# File 'lib/recurly/resource.rb', line 717 def save if new_record? || changed? clear_errors @response = API.send( persisted? ? :put : :post, path, to_xml(:delta => true) ) reload response persist! true end true rescue API::UnprocessableEntity => e apply_errors e Transaction::Error.validate! e, (self if is_a? Transaction) false end |
#save! ⇒ true
Attempts to save the record, returning true
if the record was saved and raising Invalid otherwise.
745 746 747 |
# File 'lib/recurly/resource.rb', line 745 def save! save || raise(Invalid.new(self)) end |
#signable_attributes ⇒ Object
849 850 851 |
# File 'lib/recurly/resource.rb', line 849 def signable_attributes Hash[xml_keys.map { |key| [key, self[key]] }] end |
#to_param ⇒ Object
549 550 551 |
# File 'lib/recurly/resource.rb', line 549 def to_param self[self.class.param_name] end |
#to_xml(options = {}) ⇒ String
Serializes the record to XML.
686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 |
# File 'lib/recurly/resource.rb', line 686 def to_xml = {} builder = [:builder] || XML.new("<#{self.class.member_name}/>") xml_keys.each { |key| value = respond_to?(key) ? send(key) : self[key] node = builder.add_element key # Duck-typing here is problematic because of ActiveSupport's #to_xml. case value when Resource, Subscription::AddOns value.to_xml .merge(:builder => node) when Array value.each { |e| node.add_element Helper.singularize(key), e } when Hash, Recurly::Money value.each_pair { |k, v| node.add_element k.to_s, v } else node.text = value end } builder.to_s end |
#update_attributes(attributes = {}) ⇒ true, false
Update a record with a given hash of attributes.
777 778 779 |
# File 'lib/recurly/resource.rb', line 777 def update_attributes attributes = {} self.attributes = attributes and save end |
#update_attributes!(attributes = {}) ⇒ true
Update a record with a given hash of attributes.
791 792 793 |
# File 'lib/recurly/resource.rb', line 791 def update_attributes! attributes = {} self.attributes = attributes and save! end |
#valid? ⇒ true, ...
Returns The validity of the record: true
if the record was successfully saved (or persisted and unchanged), false
if the record was not successfully saved, or nil
for a record with an unknown state (i.e. (i.e. new records that haven’t been saved and persisted records with changed attributes).
762 763 764 765 766 |
# File 'lib/recurly/resource.rb', line 762 def valid? return true if persisted? && changed_attributes.empty? return if response.nil? || (errors.empty? && changed_attributes?) errors.empty? end |
#write_attribute(key, value) ⇒ Object Also known as: []=
Sets the value of a specified attribute.
651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 |
# File 'lib/recurly/resource.rb', line 651 def write_attribute key, value if changed_attributes.key?(key = key.to_s) changed_attributes.delete key if changed_attributes[key] == value elsif self[key] != value changed_attributes[key] = self[key] end if self.class.associations.values.flatten.include? key value = fetch_association key, value # FIXME: More explicit; less magic. elsif key.end_with?('_in_cents') && !respond_to?(:currency) value = Money.new value unless value.is_a? Money end attributes[key] = value end |