gecko-ruby 0.0.4
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 +7 -0
- data/.gitignore +19 -0
- data/.rubocop.yml +9 -0
- data/.travis.yml +5 -0
- data/CHANGELOG.md +41 -0
- data/CONTRIBUTING.md +0 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +144 -0
- data/Rakefile +19 -0
- data/gecko-ruby.gemspec +34 -0
- data/generate.thor +81 -0
- data/lib/gecko-ruby.rb +1 -0
- data/lib/gecko.rb +31 -0
- data/lib/gecko/client.rb +132 -0
- data/lib/gecko/helpers/association_helper.rb +69 -0
- data/lib/gecko/helpers/inspection_helper.rb +51 -0
- data/lib/gecko/helpers/record_helper.rb +29 -0
- data/lib/gecko/helpers/serialization_helper.rb +61 -0
- data/lib/gecko/helpers/validation_helper.rb +91 -0
- data/lib/gecko/record/account.rb +66 -0
- data/lib/gecko/record/address.rb +33 -0
- data/lib/gecko/record/base.rb +66 -0
- data/lib/gecko/record/base_adapter.rb +365 -0
- data/lib/gecko/record/company.rb +41 -0
- data/lib/gecko/record/contact.rb +25 -0
- data/lib/gecko/record/currency.rb +23 -0
- data/lib/gecko/record/exceptions.rb +15 -0
- data/lib/gecko/record/fulfillment.rb +42 -0
- data/lib/gecko/record/fulfillment_line_item.rb +26 -0
- data/lib/gecko/record/image.rb +38 -0
- data/lib/gecko/record/invoice.rb +29 -0
- data/lib/gecko/record/invoice_line_item.rb +18 -0
- data/lib/gecko/record/location.rb +23 -0
- data/lib/gecko/record/order.rb +50 -0
- data/lib/gecko/record/order_line_item.rb +35 -0
- data/lib/gecko/record/product.rb +27 -0
- data/lib/gecko/record/purchase_order.rb +43 -0
- data/lib/gecko/record/purchase_order_line_item.rb +29 -0
- data/lib/gecko/record/tax_type.rb +21 -0
- data/lib/gecko/record/user.rb +44 -0
- data/lib/gecko/record/variant.rb +96 -0
- data/lib/gecko/version.rb +3 -0
- data/test/client_test.rb +29 -0
- data/test/fixtures/vcr_cassettes/accounts.yml +57 -0
- data/test/fixtures/vcr_cassettes/accounts_current.yml +57 -0
- data/test/fixtures/vcr_cassettes/addresses.yml +68 -0
- data/test/fixtures/vcr_cassettes/addresses_count.yml +58 -0
- data/test/fixtures/vcr_cassettes/companies.yml +62 -0
- data/test/fixtures/vcr_cassettes/companies_count.yml +58 -0
- data/test/fixtures/vcr_cassettes/contacts.yml +60 -0
- data/test/fixtures/vcr_cassettes/contacts_count.yml +58 -0
- data/test/fixtures/vcr_cassettes/currencies.yml +62 -0
- data/test/fixtures/vcr_cassettes/currencies_count.yml +58 -0
- data/test/fixtures/vcr_cassettes/fulfillments.yml +59 -0
- data/test/fixtures/vcr_cassettes/fulfillments_count.yml +58 -0
- data/test/fixtures/vcr_cassettes/images.yml +59 -0
- data/test/fixtures/vcr_cassettes/images_count.yml +58 -0
- data/test/fixtures/vcr_cassettes/invoice_line_items.yml +63 -0
- data/test/fixtures/vcr_cassettes/invoice_line_items_count.yml +62 -0
- data/test/fixtures/vcr_cassettes/invoices.yml +63 -0
- data/test/fixtures/vcr_cassettes/invoices_count.yml +62 -0
- data/test/fixtures/vcr_cassettes/locations.yml +65 -0
- data/test/fixtures/vcr_cassettes/locations_count.yml +58 -0
- data/test/fixtures/vcr_cassettes/order_line_items.yml +63 -0
- data/test/fixtures/vcr_cassettes/order_line_items_count.yml +62 -0
- data/test/fixtures/vcr_cassettes/orders.yml +62 -0
- data/test/fixtures/vcr_cassettes/orders_count.yml +58 -0
- data/test/fixtures/vcr_cassettes/products.yml +79 -0
- data/test/fixtures/vcr_cassettes/products_count.yml +58 -0
- data/test/fixtures/vcr_cassettes/products_new_invalid.yml +54 -0
- data/test/fixtures/vcr_cassettes/products_new_valid.yml +58 -0
- data/test/fixtures/vcr_cassettes/purchase_order_line_items.yml +64 -0
- data/test/fixtures/vcr_cassettes/purchase_order_line_items_count.yml +62 -0
- data/test/fixtures/vcr_cassettes/purchase_orders.yml +63 -0
- data/test/fixtures/vcr_cassettes/purchase_orders_count.yml +62 -0
- data/test/fixtures/vcr_cassettes/tax_types.yml +74 -0
- data/test/fixtures/vcr_cassettes/tax_types_count.yml +62 -0
- data/test/fixtures/vcr_cassettes/users.yml +60 -0
- data/test/fixtures/vcr_cassettes/users_count.yml +58 -0
- data/test/fixtures/vcr_cassettes/users_current.yml +54 -0
- data/test/fixtures/vcr_cassettes/variants.yml +60 -0
- data/test/fixtures/vcr_cassettes/variants_count.yml +58 -0
- data/test/gecko_test.rb +7 -0
- data/test/helpers/association_helper_test.rb +56 -0
- data/test/helpers/inspection_helper_test.rb +27 -0
- data/test/helpers/serialization_helper_test.rb +30 -0
- data/test/helpers/validation_helper_test.rb +24 -0
- data/test/record/account_adapter_test.rb +43 -0
- data/test/record/address_adapter_test.rb +14 -0
- data/test/record/address_test.rb +18 -0
- data/test/record/company_adapter_test.rb +14 -0
- data/test/record/company_test.rb +18 -0
- data/test/record/contact_adapter_test.rb +14 -0
- data/test/record/contact_test.rb +18 -0
- data/test/record/currency_adapter_test.rb +14 -0
- data/test/record/currency_test.rb +18 -0
- data/test/record/fulfillment_adapter_test.rb +24 -0
- data/test/record/fulfillment_line_item_adapter_test.rb +21 -0
- data/test/record/fulfillment_line_item_test.rb +18 -0
- data/test/record/fulfillment_test.rb +27 -0
- data/test/record/image_adapter_test.rb +14 -0
- data/test/record/image_test.rb +25 -0
- data/test/record/invoice_adapter_test.rb +14 -0
- data/test/record/invoice_line_item_adapter_test.rb +20 -0
- data/test/record/invoice_line_item_test.rb +18 -0
- data/test/record/invoice_test.rb +18 -0
- data/test/record/location_adapter_test.rb +14 -0
- data/test/record/location_test.rb +18 -0
- data/test/record/order_adapter_test.rb +14 -0
- data/test/record/order_line_item_adapter_test.rb +14 -0
- data/test/record/order_line_item_test.rb +18 -0
- data/test/record/order_test.rb +18 -0
- data/test/record/product_adapter_test.rb +32 -0
- data/test/record/product_test.rb +18 -0
- data/test/record/purchase_order_adapter_test.rb +14 -0
- data/test/record/purchase_order_line_item_adapter_test.rb +14 -0
- data/test/record/purchase_order_line_item_test.rb +18 -0
- data/test/record/purchase_order_test.rb +18 -0
- data/test/record/tax_type_adapter_test.rb +14 -0
- data/test/record/tax_type_test.rb +18 -0
- data/test/record/user_adapter_test.rb +27 -0
- data/test/record/user_test.rb +18 -0
- data/test/record/variant_adapter_test.rb +14 -0
- data/test/record/variant_test.rb +44 -0
- data/test/support/let.rb +10 -0
- data/test/support/shared_adapter_examples.rb +159 -0
- data/test/support/shared_record_examples.rb +21 -0
- data/test/support/testing_adapter.rb +11 -0
- data/test/support/vcr_support.rb +7 -0
- data/test/test_helper.rb +21 -0
- metadata +430 -0
@@ -0,0 +1,69 @@
|
|
1
|
+
module Gecko
|
2
|
+
module Helpers
|
3
|
+
# Helper for has_many/belongs_to relationships
|
4
|
+
module AssociationHelper
|
5
|
+
# Set up a belongs_to relationship between two classes based on a
|
6
|
+
# JSON key of {class_name}_id.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# class Gecko::Record::Variant
|
10
|
+
# belongs_to :product
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# @param [Symbol] model_name
|
14
|
+
# @param [#to_hash] options options for setting up the relationship
|
15
|
+
# @option options [String] :class_name Override the default class name
|
16
|
+
# @option options [String] :readonly (false) Whether to serialize
|
17
|
+
# this attribute
|
18
|
+
#
|
19
|
+
# @return [undefined]
|
20
|
+
#
|
21
|
+
# @api public
|
22
|
+
def belongs_to(model_name, options={})
|
23
|
+
class_name = options[:class_name] || model_name.to_s.classify
|
24
|
+
foreign_key = model_name.to_s.foreign_key.to_sym
|
25
|
+
|
26
|
+
define_method model_name do
|
27
|
+
if (id = attributes[foreign_key])
|
28
|
+
@client.adapter_for(class_name).find(id)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
attribute foreign_key, Integer, readonly: options[:readonly]
|
32
|
+
end
|
33
|
+
|
34
|
+
# Set up a has_many relationship between two classes based on a
|
35
|
+
# JSON key of {class_name}_ids.
|
36
|
+
#
|
37
|
+
# @example
|
38
|
+
# class Gecko::Record::Product
|
39
|
+
# has_many :variants
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# @param [Symbol] model_name
|
43
|
+
# @param [#to_hash] options options for setting up the relationship
|
44
|
+
# @option options [String] :class_name Override the default class name
|
45
|
+
# @option options [String] :readonly (true) Whether to serialize this
|
46
|
+
# attribute
|
47
|
+
#
|
48
|
+
# @return [undefined]
|
49
|
+
#
|
50
|
+
# @api public
|
51
|
+
def has_many(association_name, options={})
|
52
|
+
model_name = association_name.to_s.singularize
|
53
|
+
class_name = options[:class_name] || model_name.classify
|
54
|
+
foreign_key = model_name.foreign_key.pluralize.to_sym
|
55
|
+
readonly = options.key?(:readonly) ? options[:readonly] : true
|
56
|
+
|
57
|
+
define_method association_name do
|
58
|
+
ids = self.attributes[foreign_key]
|
59
|
+
if ids.any?
|
60
|
+
@client.adapter_for(class_name).find_many(ids)
|
61
|
+
else
|
62
|
+
[]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
attribute foreign_key, Array[Integer], readonly: readonly
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Gecko
|
2
|
+
module Helpers
|
3
|
+
# Helper for providing custom #inspect values to Records
|
4
|
+
module InspectionHelper
|
5
|
+
# Overrides the default inspect to just return the defined attributes
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# company.inspect #=> <Gecko::Record::Company id=123 name="Gecko Inc">
|
9
|
+
#
|
10
|
+
# @return [String]
|
11
|
+
#
|
12
|
+
# @api public
|
13
|
+
def inspect
|
14
|
+
inspection = self.class.attribute_set.map do |attribute|
|
15
|
+
name = attribute.name
|
16
|
+
"#{name}: #{attribute_for_inspect(name)}"
|
17
|
+
end.join(', ')
|
18
|
+
"#<#{self.class} #{inspection}>"
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
# Returns an #inspect-like string for the value of the attribute
|
24
|
+
# attr_name.
|
25
|
+
# String attributes are truncated up to 50 characters,
|
26
|
+
# and Date and Time attributes are returned in the :db format.
|
27
|
+
# Other attributes return the value of #inspect without modification.
|
28
|
+
# Duplicated from Rails implementation
|
29
|
+
#
|
30
|
+
# @example
|
31
|
+
# company.inspect #=> <Gecko::Record::Company id=123 name="Gecko Inc">
|
32
|
+
#
|
33
|
+
# @return [String]
|
34
|
+
#
|
35
|
+
# @api private
|
36
|
+
def attribute_for_inspect(attr_name)
|
37
|
+
value = attributes[attr_name]
|
38
|
+
|
39
|
+
if value.is_a?(String) && value.length > 50
|
40
|
+
"#{value[0..50]}...".inspect
|
41
|
+
elsif value.is_a?(DateTime) || value.is_a?(Time)
|
42
|
+
%("#{value.strftime("%Y-%m-%d %H:%M:%S")}")
|
43
|
+
elsif value.is_a?(Date)
|
44
|
+
%("#{value.strftime("%Y-%m-%d")}")
|
45
|
+
else
|
46
|
+
value.inspect
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Gecko
|
2
|
+
module Helpers
|
3
|
+
# Helper for registering valid record types
|
4
|
+
module RecordHelper
|
5
|
+
# Registers a record type on the Gecko::Client
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# class Gecko::Client
|
9
|
+
# record :Invoice
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# @return [undefined]
|
13
|
+
#
|
14
|
+
# @api private
|
15
|
+
def record(record_type)
|
16
|
+
define_method record_type do
|
17
|
+
adapter_cache = "@#{record_type}_cache".to_sym
|
18
|
+
unless instance_variable_defined?(adapter_cache)
|
19
|
+
adapter_name = "#{record_type}Adapter".to_sym
|
20
|
+
adapter_klass = Gecko::Record.const_get(adapter_name)
|
21
|
+
adapter = adapter_klass.new(self, record_type)
|
22
|
+
instance_variable_set(adapter_cache, adapter)
|
23
|
+
end
|
24
|
+
instance_variable_get(adapter_cache)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Gecko
|
2
|
+
module Helpers
|
3
|
+
# Provides serialization to records
|
4
|
+
module SerializationHelper
|
5
|
+
# Returns a full JSON representation of a record
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# product.as_json #=> {product: {id: 12, name: "Big"}}
|
9
|
+
#
|
10
|
+
# @return [Hash]
|
11
|
+
#
|
12
|
+
# @api private
|
13
|
+
def as_json
|
14
|
+
{
|
15
|
+
root => serializable_hash
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
# Return a serialized hash of the record's attributes
|
20
|
+
#
|
21
|
+
# @example
|
22
|
+
# product.serializable_hash #=> {id: 12, name: "Big"}
|
23
|
+
#
|
24
|
+
# @return [Hash]
|
25
|
+
#
|
26
|
+
# @api private
|
27
|
+
def serializable_hash
|
28
|
+
attribute_hash = {}
|
29
|
+
attribute_set.each do |attribute|
|
30
|
+
next if attribute.options[:readonly]
|
31
|
+
serialize_attribute(attribute_hash, attribute)
|
32
|
+
end
|
33
|
+
attribute_hash
|
34
|
+
end
|
35
|
+
|
36
|
+
# Serialize a single attribute
|
37
|
+
#
|
38
|
+
# @param [Hash] attribute_hash Serialized record being iterated over
|
39
|
+
# @param [Virtus::Attribute] attribute The attribute being serialized
|
40
|
+
#
|
41
|
+
# @return [undefined]
|
42
|
+
#
|
43
|
+
# @api private
|
44
|
+
def serialize_attribute(attribute_hash, attribute)
|
45
|
+
attribute_hash[attribute.name] = attributes[attribute.name]
|
46
|
+
end
|
47
|
+
|
48
|
+
# Return JSON root key for a record
|
49
|
+
#
|
50
|
+
# @example
|
51
|
+
# product.root #=> "product"
|
52
|
+
#
|
53
|
+
# @return [String]
|
54
|
+
#
|
55
|
+
# @api private
|
56
|
+
def root
|
57
|
+
self.class.demodulized_name.underscore.to_sym
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Gecko
|
2
|
+
module Helpers
|
3
|
+
# Provides record validation
|
4
|
+
module ValidationHelper
|
5
|
+
# Returns whether a record is considered valid or not
|
6
|
+
#
|
7
|
+
# @return [Boolean]
|
8
|
+
#
|
9
|
+
# @api public
|
10
|
+
def valid?
|
11
|
+
errors.empty?
|
12
|
+
end
|
13
|
+
|
14
|
+
# Returns the validation errors object for the record
|
15
|
+
#
|
16
|
+
# @return [Gecko::Errors]
|
17
|
+
#
|
18
|
+
# @api public
|
19
|
+
def errors
|
20
|
+
@errors ||= Gecko::Errors.new(self)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Errors
|
26
|
+
# The hash of errors for this record
|
27
|
+
#
|
28
|
+
# @return [Hash]
|
29
|
+
#
|
30
|
+
# @api public
|
31
|
+
attr_reader :messages
|
32
|
+
|
33
|
+
# Set up the error object
|
34
|
+
#
|
35
|
+
# @api private
|
36
|
+
def initialize(base)
|
37
|
+
@base = base
|
38
|
+
@messages = {}
|
39
|
+
end
|
40
|
+
|
41
|
+
# Fetch the errors for a specific attribute
|
42
|
+
#
|
43
|
+
# @example
|
44
|
+
# product.errors[:name]
|
45
|
+
# #=> ["can't be blank"]
|
46
|
+
#
|
47
|
+
# @params [Symbol] :attribute
|
48
|
+
#
|
49
|
+
# @return [Array]
|
50
|
+
#
|
51
|
+
# @api public
|
52
|
+
def [](attribute)
|
53
|
+
messages[attribute.to_sym]
|
54
|
+
end
|
55
|
+
|
56
|
+
# Clear the validation errors
|
57
|
+
#
|
58
|
+
# @example
|
59
|
+
# product.errors.clear
|
60
|
+
#
|
61
|
+
# @return [undefined]
|
62
|
+
#
|
63
|
+
# @api public
|
64
|
+
def clear
|
65
|
+
@messages.clear
|
66
|
+
end
|
67
|
+
|
68
|
+
# Whether there are any errors
|
69
|
+
#
|
70
|
+
# @return [Boolean]
|
71
|
+
#
|
72
|
+
# @api public
|
73
|
+
def empty?
|
74
|
+
messages.all? { |k, v| v && v.empty? && !v.is_a?(String) }
|
75
|
+
end
|
76
|
+
|
77
|
+
# Parse JSON errors response into the error object
|
78
|
+
#
|
79
|
+
# @params [#to_hash] :error_hash hash of errors where key is an attribute
|
80
|
+
# name and value is an array of error strings
|
81
|
+
#
|
82
|
+
# @return [undefined]
|
83
|
+
#
|
84
|
+
# @api private
|
85
|
+
def from_response(error_hash)
|
86
|
+
error_hash.each do |attr, errors|
|
87
|
+
@messages[attr.to_sym] = errors
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'gecko/record/base'
|
2
|
+
|
3
|
+
module Gecko
|
4
|
+
module Record
|
5
|
+
class Account < Base
|
6
|
+
has_many :users
|
7
|
+
has_many :locations
|
8
|
+
|
9
|
+
attribute :name, String
|
10
|
+
attribute :industry, String
|
11
|
+
attribute :logo_url, String, readonly: true
|
12
|
+
attribute :website, String
|
13
|
+
attribute :tax_number, String
|
14
|
+
attribute :country, String
|
15
|
+
attribute :time_zone, String
|
16
|
+
|
17
|
+
attribute :contact_email, String
|
18
|
+
attribute :contact_mobile, String
|
19
|
+
attribute :contact_phone, String
|
20
|
+
|
21
|
+
attribute :invoice_details, String
|
22
|
+
attribute :order_details, String
|
23
|
+
attribute :quote_details, String
|
24
|
+
|
25
|
+
attribute :default_tax_rate, String
|
26
|
+
|
27
|
+
attribute :default_tax_type_id, Integer
|
28
|
+
|
29
|
+
attribute :tax_number_label, String
|
30
|
+
attribute :tax_label, String
|
31
|
+
|
32
|
+
belongs_to :billing_contact, class_name: "User"
|
33
|
+
belongs_to :primary_location, class_name: "Location"
|
34
|
+
belongs_to :primary_billing_location, class_name: "Location"
|
35
|
+
|
36
|
+
# belongs_to :default_currency, class_name: "Currency"
|
37
|
+
# belongs_to :default_payment_term, class_name: "PaymentTerm"
|
38
|
+
# belongs_to :default_purchase_order_price_list, class_name: "PriceList"
|
39
|
+
# belongs_to :default_order_price_list, class_name: "PriceList"
|
40
|
+
|
41
|
+
# attribute :stock_level_warn, String
|
42
|
+
# attribute :subscription_name, String
|
43
|
+
# attribute :subscription_price, String
|
44
|
+
# attribute :annual_subscription_price, String
|
45
|
+
# attribute :expires_at, String
|
46
|
+
end
|
47
|
+
|
48
|
+
class AccountAdapter < BaseAdapter
|
49
|
+
undef :count
|
50
|
+
undef :build
|
51
|
+
|
52
|
+
# Return the account for the logged in user
|
53
|
+
#
|
54
|
+
# @return [Gecko::Record::Account]
|
55
|
+
#
|
56
|
+
# @api public
|
57
|
+
def current
|
58
|
+
if self.has_record_for_id?(:current)
|
59
|
+
record_for_id(:current)
|
60
|
+
else
|
61
|
+
@identity_map[:current] = find(:current)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'gecko/record/base'
|
2
|
+
|
3
|
+
module Gecko
|
4
|
+
module Record
|
5
|
+
class Address < Base
|
6
|
+
belongs_to :company
|
7
|
+
|
8
|
+
attribute :phone_number, String
|
9
|
+
attribute :email, String
|
10
|
+
|
11
|
+
attribute :label, String
|
12
|
+
attribute :company_name, String
|
13
|
+
attribute :address1, String
|
14
|
+
attribute :address2, String
|
15
|
+
attribute :suburb, String
|
16
|
+
attribute :city, String
|
17
|
+
attribute :state, String
|
18
|
+
attribute :country, String
|
19
|
+
attribute :zip_code, String
|
20
|
+
|
21
|
+
attribute :status, String, readonly: true
|
22
|
+
|
23
|
+
alias_method :country_code, :country
|
24
|
+
end
|
25
|
+
|
26
|
+
class AddressAdapter < BaseAdapter
|
27
|
+
# Override plural_path to properly pluralize address
|
28
|
+
def plural_path
|
29
|
+
'addresses'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'gecko/helpers/association_helper'
|
2
|
+
require 'gecko/helpers/inspection_helper'
|
3
|
+
require 'gecko/helpers/serialization_helper'
|
4
|
+
require 'gecko/helpers/validation_helper'
|
5
|
+
|
6
|
+
module Gecko
|
7
|
+
module Record
|
8
|
+
class Base
|
9
|
+
include Virtus.model
|
10
|
+
extend Gecko::Helpers::AssociationHelper
|
11
|
+
include Gecko::Helpers::InspectionHelper
|
12
|
+
include Gecko::Helpers::SerializationHelper
|
13
|
+
include Gecko::Helpers::ValidationHelper
|
14
|
+
|
15
|
+
# Set up the default attributes associated with all records
|
16
|
+
attribute :id, Integer, readonly: true
|
17
|
+
attribute :updated_at, DateTime, readonly: true
|
18
|
+
attribute :created_at, DateTime, readonly: true
|
19
|
+
|
20
|
+
# Overrides the default Virtus functionality to store:
|
21
|
+
# - The Gecko::Client used to create the object
|
22
|
+
# - a raw copy of the attributes for the association helpers to read from
|
23
|
+
#
|
24
|
+
# @return [undefined]
|
25
|
+
#
|
26
|
+
# @api private
|
27
|
+
def initialize(client, attributes={})
|
28
|
+
super(attributes)
|
29
|
+
@client = client
|
30
|
+
end
|
31
|
+
|
32
|
+
# Whether the record has been persisted
|
33
|
+
#
|
34
|
+
# @example
|
35
|
+
# variant.persisted? #=> true
|
36
|
+
#
|
37
|
+
# @return <Boolean>
|
38
|
+
#
|
39
|
+
# @api public
|
40
|
+
def persisted?
|
41
|
+
!!id
|
42
|
+
end
|
43
|
+
|
44
|
+
# Save a record
|
45
|
+
#
|
46
|
+
# @return <Gecko::Record::Base>
|
47
|
+
#
|
48
|
+
# @api public
|
49
|
+
def save
|
50
|
+
@client.adapter_for(self.class.demodulized_name).save(self)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Return the demodulized class name
|
54
|
+
#
|
55
|
+
# @example
|
56
|
+
# Gecko::Record::Product.demodulized_name #=> "Product"
|
57
|
+
#
|
58
|
+
# @return [String]
|
59
|
+
#
|
60
|
+
# @api private
|
61
|
+
def self.demodulized_name
|
62
|
+
self.name.split('::').last
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|