Class: Spree::Address

Inherits:
Base
  • Object
show all
Extended by:
ActiveModel::ForbiddenAttributesProtection
Defined in:
app/models/spree/address.rb,
app/models/spree/address/name.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`.

Defined Under Namespace

Classes: Name, StateValidator

Constant Summary collapse

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

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

display_includes

Methods included from Core::Permalinks

#generate_permalink, #save_permalink

Class Method Details

.build_default(*args, &block) ⇒ Address



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

def self.build_default(*args, &block)
  where(country: Spree::Country.default).build(*args, &block)
end

.factory(attributes) ⇒ Address



41
42
43
44
# File 'app/models/spree/address.rb', line 41

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

.immutable_merge(existing_address, new_attributes) ⇒ Address

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



48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'app/models/spree/address.rb', line 48

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

.value_attributes(base_attributes, merge_attributes = {}) ⇒ Hash



64
65
66
67
# File 'app/models/spree/address.rb', line 64

def self.value_attributes(base_attributes, merge_attributes = {})
  base = base_attributes.stringify_keys.merge(merge_attributes.stringify_keys)
  base.except(*DB_ONLY_ATTRS)
end

Instance Method Details

#==(other_address) ⇒ Boolean

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.



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

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

#active_merchant_hashHash



96
97
98
99
100
101
102
103
104
105
106
107
# File 'app/models/spree/address.rb', line 96

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

#country_isoObject



136
137
138
# File 'app/models/spree/address.rb', line 136

def country_iso
  country && country.iso
end

#country_iso=(iso) ⇒ Country

Returns 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



132
133
134
# File 'app/models/spree/address.rb', line 132

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

#readonly?Boolean

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.



125
126
127
# File 'app/models/spree/address.rb', line 125

def readonly?
  persisted?
end

#require_phone?true



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

def require_phone?
  Spree::Config[:address_requires_phone]
end

#require_zipcode?true



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

def require_zipcode?
  true
end

#state_textString



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

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

#taxation_attributesObject



74
75
76
# File 'app/models/spree/address.rb', line 74

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

#to_sObject



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

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

#value_attributesHash



70
71
72
# File 'app/models/spree/address.rb', line 70

def value_attributes
  self.class.value_attributes(attributes)
end