Class: Formstar::Base

Inherits:
Object
  • Object
show all
Includes:
ActiveModel::Attributes, ActiveModel::Model, ActiveModel::Validations::Callbacks, AfterCommitEverywhere
Defined in:
lib/formstar/base.rb

Direct Known Subclasses

ApplicationForm

Defined Under Namespace

Classes: NoModelError

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeBase

Returns a new instance of Base.

Raises:

  • (NotImplementedError)


23
24
25
26
27
28
29
30
31
32
# File 'lib/formstar/base.rb', line 23

def initialize(...)
  raise NotImplementedError.new("`#{self.class.name}` is abstract and cannot be instantiated directly.") if ["Formstar::Base", "ApplicationForm"].include?(self.class.name)

  @form_succeeded = nil
   = false

  run_callbacks(:initialize) do
    super(...)
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object (private)



141
142
143
144
145
146
147
# File 'lib/formstar/base.rb', line 141

def method_missing(method, *args, &block)
  if form_model_defined? && method.to_sym != self.class.config[:model][:name]
    form_model.send(method, *args, &block)
  else
    super
  end
end

Class Attribute Details

.configObject (readonly)

Returns the value of attribute config.



151
152
153
# File 'lib/formstar/base.rb', line 151

def config
  @config
end

.form_attribute_namesObject (readonly)

Returns the value of attribute form_attribute_names.



152
153
154
# File 'lib/formstar/base.rb', line 152

def form_attribute_names
  @form_attribute_names
end

Instance Attribute Details

#form_submittedObject (readonly)

Returns the value of attribute form_submitted.



19
20
21
# File 'lib/formstar/base.rb', line 19

def 
  
end

#form_succeededObject (readonly)

Returns the value of attribute form_succeeded.



18
19
20
# File 'lib/formstar/base.rb', line 18

def form_succeeded
  @form_succeeded
end

Class Method Details

.attr_form(name) ⇒ Object



176
177
178
179
# File 'lib/formstar/base.rb', line 176

def attr_form(name, ...)
  form_attribute_names.add(name.to_sym)
  attribute(name, ...)
end

.human_attribute_name(attribute, options = {}) ⇒ Object



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/formstar/base.rb', line 213

def human_attribute_name(attribute, options = {})
  # Base errors for a form will never fall back to the underlying model.
  # So we can safely always delegate the translation lookup back to active model
  # which will build up the correct lookup paths.
  return attribute if attribute.to_sym == :base

  I18n.t!("#{i18n_scope}.attributes.#{model_name.i18n_key}.#{attribute}")
rescue I18n::MissingTranslationData => e
  fallback_value = nil

  if config[:model_translation_fallback_enabled]
    if config[:model]
      form_model_klass = config[:model][:klass]
    else
      form_model_klass = nil
    end

    fallback_klass = config[:model_translation_fallback_class_name] || form_model_klass
    fallback_value = fallback_klass.human_attribute_name(attribute, options) if fallback_klass
  end

  if fallback_value
    fallback_value
  else
    raise e
  end
end

.i18n_scopeObject



209
210
211
# File 'lib/formstar/base.rb', line 209

def i18n_scope
  :form
end

.inherited(subclass) ⇒ Object



154
155
156
# File 'lib/formstar/base.rb', line 154

def inherited(subclass)
  subclass.instance_variable_set(:@config, self.config.dup)
end

.model_nameObject



192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/formstar/base.rb', line 192

def model_name
  return @model_name unless @model_name.nil?

  if config[:model]
    @model_name = ActiveModel::Name.new(config[:model][:klass])
    @model_name.i18n_key = self.name.underscore
  else
    @model_name = ActiveModel::Name.new(self)
  end

  @model_name
end

.model_translation_fallback(enabled, class_name: nil) ⇒ Object



167
168
169
170
# File 'lib/formstar/base.rb', line 167

def model_translation_fallback(enabled, class_name: nil)
  config[:model_translation_fallback_enabled] = enabled
  config[:model_translation_fallback_class_name] = class_name&.safe_constantize
end

.submit_within_transaction(enabled) ⇒ Object



172
173
174
# File 'lib/formstar/base.rb', line 172

def submit_within_transaction(enabled)
  config[:submit_within_transaction_enabled] = enabled
end

.with_model(name, class_name: name) ⇒ Object

Raises:

  • (ArgumentError)


181
182
183
184
185
186
187
188
189
190
# File 'lib/formstar/base.rb', line 181

def with_model(name, class_name: name)
  name = name.to_sym
  class_name = class_name.to_s.classify
  klass = Object.const_get(class_name)

  # Don't accept models that are modules.
  raise ArgumentError.new("Expected an ActiveRecord model, got `#{class_name}`") unless klass < ActiveRecord::Base

  config[:model] = { name: name, klass: klass }
end

Instance Method Details

#form_attributesObject



46
47
48
49
50
51
52
53
54
55
# File 'lib/formstar/base.rb', line 46

def form_attributes
  return @form_attributes unless @form_attributes.nil?

  @form_attributes = {}
  self.class.form_attribute_names.each do |attr_name|
    @form_attributes[attr_name] = send(attr_name)
  end

  @form_attributes
end

#modelObject

Raises:



89
90
91
92
# File 'lib/formstar/base.rb', line 89

def model
  raise NoModelError.new unless form_model_defined?
  self.form_model
end

#model=(new_model) ⇒ Object

Raises:



94
95
96
97
# File 'lib/formstar/base.rb', line 94

def model=(new_model)
  raise NoModelError.new unless form_model_defined?
  self.form_model = new_model
end

#save(**opts) ⇒ Object



57
58
59
60
61
# File 'lib/formstar/base.rb', line 57

def save(**opts)
  save!(**opts)
rescue
  false
end

#save!(**opts) ⇒ Object



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
# File 'lib/formstar/base.rb', line 63

def save!(**opts)
   = true
  validate!(context: opts[:context]) unless opts[:validate] == false

  perform_submit = -> do
    run_callbacks(:save) do
      submit
    end
  end

  if self.class.config[:submit_within_transaction_enabled]
    ActiveRecord::Base.transaction do
      perform_submit.call
    end
  else
    perform_submit.call
  end

  after_commit { run_callbacks(:commit) }

  @form_succeeded = true
rescue => e
  @form_succeeded = false
  raise e
end

#submitObject

Raises:

  • (NotImplementedError)


34
35
36
# File 'lib/formstar/base.rb', line 34

def submit
  raise NotImplementedError
end

#submitted?Boolean

Returns:

  • (Boolean)


42
43
44
# File 'lib/formstar/base.rb', line 42

def 
  
end

#succeeded?Boolean

Returns:

  • (Boolean)


38
39
40
# File 'lib/formstar/base.rb', line 38

def succeeded?
  @form_succeeded
end