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



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

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

.factory(attributes) ⇒ Address



43
44
45
46
# File 'app/models/spree/address.rb', line 43

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



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

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



66
67
68
69
# File 'app/models/spree/address.rb', line 66

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.



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

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

#active_merchant_hashHash



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

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

#country_isoObject



138
139
140
# File 'app/models/spree/address.rb', line 138

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



134
135
136
# File 'app/models/spree/address.rb', line 134

def country_iso=(iso)
  self.country = Spree::Country.find_by!(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.



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

def readonly?
  persisted?
end

#require_phone?true



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

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

#require_zipcode?true



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

def require_zipcode?
  true
end

#state_textString



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

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

#taxation_attributesObject



76
77
78
# File 'app/models/spree/address.rb', line 76

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

#to_sObject



85
86
87
# File 'app/models/spree/address.rb', line 85

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

#value_attributesHash



72
73
74
# File 'app/models/spree/address.rb', line 72

def value_attributes
  self.class.value_attributes(attributes)
end