Module: Spree::Preferences::PreferableClassMethods

Defined in:
lib/spree/preferences/preferable_class_methods.rb

Constant Summary collapse

DEFAULT_ADMIN_FORM_PREFERENCE_TYPES =
%i(
  boolean
  decimal
  integer
  password
  string
  text
  encrypted_string
)

Instance Method Summary collapse

Instance Method Details

#allowed_admin_form_preference_typesArray

List of preference types allowed as form fields in the Solidus admin

Overwrite this method in your class that includes Spree::Preferable if you want to provide more fields. If you do so, you also need to provide a preference field partial that lives in:

app/views/spree/admin/shared/preference_fields/

Returns:

  • (Array)

136
137
138
# File 'lib/spree/preferences/preferable_class_methods.rb', line 136

def allowed_admin_form_preference_types
  DEFAULT_ADMIN_FORM_PREFERENCE_TYPES
end

#defined_preferencesObject


18
19
20
# File 'lib/spree/preferences/preferable_class_methods.rb', line 18

def defined_preferences
  []
end

#preference(name, type, options = {}) ⇒ Object


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/spree/preferences/preferable_class_methods.rb', line 22

def preference(name, type, options = {})
  options.assert_valid_keys(:default, :encryption_key)

  if type == :encrypted_string
    preference_encryptor = preference_encryptor(options)
    options[:default] = preference_encryptor.encrypt(options[:default])
  end

  default = begin
              given = options[:default]
              if ancestors.include?(Spree::Preferences::Configuration) &&
                 given.is_a?(Proc) &&
                 given.lambda? &&
                 given.arity.zero?
                Spree::Deprecation.warn <<~MSG
                  The arity of a proc given as the default for a preference
                  has changed from 0 to 1 on Solidus 3.1. The Solidus
                  version for the loaded preference defaults is given as the
                  proc's argument from this point on.

                  If you don't need to return a different default value
                  depending on the loaded Solidus version, you can change
                  the proc so that it doesn't have lambda semantics (lambdas
                  raise when extra arguments are supplied, while raw procs
                  don't). E.g.:

                  preference :foo, :string, default: proc { true }

                  If you want to branch on the provided Solidus version, you can do like the following:

                  versioned_preference :foo, :string, initial_value: true, boundaries: { "3.2.0" => false }

                MSG
                ->(_default_context) { given.call }
              elsif given.is_a?(Proc)
                given
              else
                proc { given }
              end
            end

  # The defined preferences on a class are all those defined directly on
  # that class as well as those defined on ancestors.
  # We store these as a class instance variable on each class which has a
  # preference. super() collects preferences defined on ancestors.
  singleton_preferences = (@defined_singleton_preferences ||= [])
  singleton_preferences << name.to_sym

  define_singleton_method :defined_preferences do
    super() + singleton_preferences
  end

  # cache_key will be nil for new objects, then if we check if there
  # is a pending preference before going to default
  define_method preference_getter_method(name) do
    value = preferences.fetch(name) do
      default.call(*context_for_default)
    end
    value = preference_encryptor.decrypt(value) if preference_encryptor.present?
    value
  end

  define_method preference_setter_method(name) do |value|
    value = convert_preference_value(value, type, preference_encryptor)
    preferences[name] = value

    # If this is an activerecord object, we need to inform
    # ActiveRecord::Dirty that this value has changed, since this is an
    # in-place update to the preferences hash.
    preferences_will_change! if respond_to?(:preferences_will_change!)
  end

  define_method preference_default_getter_method(name) do
    default.call(*context_for_default)
  end

  define_method preference_type_getter_method(name) do
    type
  end
end

#preference_default_getter_method(name) ⇒ Object


111
112
113
# File 'lib/spree/preferences/preferable_class_methods.rb', line 111

def preference_default_getter_method(name)
  "preferred_#{name}_default".to_sym
end

#preference_encryptor(options) ⇒ Object


119
120
121
122
123
124
125
# File 'lib/spree/preferences/preferable_class_methods.rb', line 119

def preference_encryptor(options)
  key = options[:encryption_key] ||
        ENV['SOLIDUS_PREFERENCES_MASTER_KEY'] ||
        Rails.application.credentials.secret_key_base

  Spree::Encryptor.new(key)
end

#preference_getter_method(name) ⇒ Object


103
104
105
# File 'lib/spree/preferences/preferable_class_methods.rb', line 103

def preference_getter_method(name)
  "preferred_#{name}".to_sym
end

#preference_setter_method(name) ⇒ Object


107
108
109
# File 'lib/spree/preferences/preferable_class_methods.rb', line 107

def preference_setter_method(name)
   "preferred_#{name}=".to_sym
end

#preference_type_getter_method(name) ⇒ Object


115
116
117
# File 'lib/spree/preferences/preferable_class_methods.rb', line 115

def preference_type_getter_method(name)
  "preferred_#{name}_type".to_sym
end