Class: Spree::Address

Inherits:
Base
  • Object
show all
Extended by:
ActiveModel::ForbiddenAttributesProtection
Defined in:
app/models/spree/address.rb

Overview

`Spree::Address` provides the foundational ActiveRecord model for recording and validating address information for `Spree::Order`, `Spree::Shipment`, `Spree::UserAddress`, and `Spree::Carton`.

Constant Summary

DB_ONLY_ATTRS =
%w(id updated_at created_at)
TAXATION_ATTRS =
%w(state_id country_id zipcode)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Methods inherited from Base

display_includes, #initialize_preference_defaults, page, preference

Methods included from Preferences::Preferable

#default_preferences, #defined_preferences, #get_preference, #has_preference!, #has_preference?, #preference_default, #preference_type, #set_preference

Class Method Details

+ (Object) build_default



32
33
34
# File 'app/models/spree/address.rb', line 32

def self.build_default
  new(country: Spree::Country.default)
end

+ (Address) factory(attributes)

Returns an equal address already in the database or a newly created one

Returns:

  • (Address)

    an equal address already in the database or a newly created one



37
38
39
40
# File 'app/models/spree/address.rb', line 37

def self.factory(attributes)
  full_attributes = value_attributes(column_defaults, new(attributes).attributes)
  find_or_initialize_by(full_attributes)
end

+ (Address) immutable_merge(existing_address, new_attributes)

@note, this may return existing_address if there are no changes to value equality

Returns:

  • (Address)

    address from existing address plus new_attributes as diff



44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'app/models/spree/address.rb', line 44

def self.immutable_merge(existing_address, new_attributes)
  # Ensure new_attributes is a sanitized hash
  new_attributes = sanitize_for_mass_assignment(new_attributes)

  return factory(new_attributes) if existing_address.nil?

  merged_attributes = value_attributes(existing_address.attributes, new_attributes)
  new_address = factory(merged_attributes)
  if existing_address == new_address
    existing_address
  else
    new_address
  end
end

+ (Hash) value_attributes(base_attributes, merge_attributes = nil)

Returns hash of attributes contributing to value equality with optional merge

Returns:

  • (Hash)

    hash of attributes contributing to value equality with optional merge



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'app/models/spree/address.rb', line 60

def self.value_attributes(base_attributes, merge_attributes = nil)
  # dup because we may modify firstname/lastname.
  base = base_attributes.dup

  base.stringify_keys!

  if merge_attributes
    base.merge!(merge_attributes.stringify_keys)
  end

  # TODO: Deprecate these aliased attributes
  base['firstname'] = base.delete('first_name') if base.key?('first_name')
  base['lastname'] = base.delete('last_name') if base.key?('last_name')

  base.except!(*DB_ONLY_ATTRS)
end

Instance Method Details

- (Boolean) ==(other_address)

Note:

This compares the addresses based on only the fields that make up the logical “address” and excludes the database specific fields (id, created_at, updated_at).

Returns true if the two addresses have the same address fields

Returns:

  • (Boolean)

    true if the two addresses have the same address fields



103
104
105
106
# File 'app/models/spree/address.rb', line 103

def ==(other_address)
  return false unless other_address && other_address.respond_to?(:value_attributes)
  value_attributes == other_address.value_attributes
end

- (Hash) active_merchant_hash

Returns an ActiveMerchant compatible address hash

Returns:

  • (Hash)

    an ActiveMerchant compatible address hash



132
133
134
135
136
137
138
139
140
141
142
143
# File 'app/models/spree/address.rb', line 132

def active_merchant_hash
  {
    name: full_name,
    address1: address1,
    address2: address2,
    city: city,
    state: state_text,
    zip: zipcode,
    country: country.try(:iso),
    phone: phone
  }
end

- (Boolean) blank?

This exists because the default Object#blank?, checks empty? if it is defined, and we have defined empty. This should be removed once empty? is removed

Returns:

  • (Boolean)


127
128
129
# File 'app/models/spree/address.rb', line 127

def blank?
  false
end

- (Country) country_iso=(iso)

Returns setter that sets self.country to the Country with a matching 2 letter iso

Parameters:

  • iso (String)

    2 letter Country ISO

Returns:

  • (Country)

    setter that sets self.country to the Country with a matching 2 letter iso

Raises:

  • (ActiveRecord::RecordNotFound)

    if country with the iso doesn't exist



168
169
170
# File 'app/models/spree/address.rb', line 168

def country_iso=(iso)
  self.country = Spree::Country.find_by!(iso: iso)
end

- (Boolean) empty?

Deprecated.

Do not use this

Returns:

  • (Boolean)


119
120
121
122
# File 'app/models/spree/address.rb', line 119

def empty?
  Spree::Deprecation.warn("Address#empty? is deprecated.", caller)
  attributes.except('id', 'created_at', 'updated_at', 'country_id').all? { |_, v| v.nil? }
end

- (String) full_name

Returns the full name on this address

Returns:

  • (String)

    the full name on this address



87
88
89
# File 'app/models/spree/address.rb', line 87

def full_name
  "#{firstname} #{lastname}".strip
end

- (Boolean) readonly?

This is set in order to preserve immutability of Addresses. Use #dup to create new records as required, but it probably won't be required as often as you think. Since addresses do not change, you won't accidentally alter historical data.

Returns:

  • (Boolean)


161
162
163
# File 'app/models/spree/address.rb', line 161

def readonly?
  persisted?
end

- (true) require_phone?

TODO:

Remove this from the public API if possible.

Returns whether or not the address requires a phone number to be valid

Returns:

  • (true)

    whether or not the address requires a phone number to be valid



148
149
150
# File 'app/models/spree/address.rb', line 148

def require_phone?
  true
end

- (true) require_zipcode?

TODO:

Remove this from the public API if possible.

Returns whether or not the address requires a zipcode to be valid

Returns:

  • (true)

    whether or not the address requires a zipcode to be valid



154
155
156
# File 'app/models/spree/address.rb', line 154

def require_zipcode?
  true
end

- (Object) same_as(other_address)



113
114
115
116
# File 'app/models/spree/address.rb', line 113

def same_as(other_address)
  Spree::Deprecation.warn("Address#same_as is deprecated. It's equivalent to Address.==", caller)
  self == other_address
end

- (Boolean) same_as?(other_address)

Returns:

  • (Boolean)


108
109
110
111
# File 'app/models/spree/address.rb', line 108

def same_as?(other_address)
  Spree::Deprecation.warn("Address#same_as? is deprecated. It's equivalent to Address.==", caller)
  self == other_address
end

- (String) state_text

Returns a string representation of this state

Returns:

  • (String)

    a string representation of this state



92
93
94
# File 'app/models/spree/address.rb', line 92

def state_text
  state.try(:abbr) || state.try(:name) || state_name
end

- (Object) taxation_attributes



82
83
84
# File 'app/models/spree/address.rb', line 82

def taxation_attributes
  self.class.value_attributes(attributes.slice(*TAXATION_ATTRS))
end

- (Object) to_s



96
97
98
# File 'app/models/spree/address.rb', line 96

def to_s
  "#{full_name}: #{address1}"
end

- (Hash) value_attributes

Returns hash of attributes contributing to value equality

Returns:

  • (Hash)

    hash of attributes contributing to value equality



78
79
80
# File 'app/models/spree/address.rb', line 78

def value_attributes
  self.class.value_attributes(attributes)
end