Class: Kadmin::Form
- Inherits:
-
Object
- Object
- Kadmin::Form
- Extended by:
- ActiveModel::Translation
- Includes:
- ActiveModel::Validations, ActiveRecord::AttributeAssignment
- Defined in:
- app/components/kadmin/form.rb
Overview
Parsing is done by using attribute setters. If you have an attribute called name, then add a reader/writer for it, name and name=, and perform the parsing in name=. If there is no parsing to be done, you can simply delegate the method to the underlying model.
If the attribute is a nested form, in the writer, simply instantiate that form, and pass the attributes on to it, then update the model's association (if any) to reflect the changes.
Validation is performed like on a normal model or ActiveRecord object. If you have no extra validation to perform than that of the model, simply delegate the validate and valid? methods to the model.
To use nested forms, you need to add a reader and a writer. For example, for a form called Person, with potentially X nested Person forms as children, you would have:
Instance Attribute Summary collapse
-
#model ⇒ ActiveModel::Model
readonly
Underlying model to populate.
Attributes assignment/manipulation collapse
- .delegate_association(association, to:) ⇒ Object
-
.delegate_attributes(*attributes) ⇒ Object
Delegates the list of attributes to the model, both readers and writers.
- #associated_forms ⇒ Object
-
#sanitize_for_mass_assignment(attributes) ⇒ Object
For now, we overload the method to accept all attributes.
Persistence collapse
Instance Method Summary collapse
-
#initialize(model) ⇒ Form
constructor
A new instance of Form.
- #to_model ⇒ Object
Constructor Details
#initialize(model) ⇒ Form
Returns a new instance of Form
42 43 44 45 46 |
# File 'app/components/kadmin/form.rb', line 42 def initialize(model) @errors = ActiveModel::Errors.new(self) @model = model @form_input = {} end |
Instance Attribute Details
#model ⇒ ActiveModel::Model (readonly)
Returns underlying model to populate
38 39 40 |
# File 'app/components/kadmin/form.rb', line 38 def model @model end |
Class Method Details
.delegate_association(association, to:) ⇒ Object
93 94 95 96 97 98 99 100 101 102 |
# File 'app/components/kadmin/form.rb', line 93 def delegate_association(association, to:) self.associations[association] = to # add a reader attribute class_eval <<~METHOD, __FILE__, __LINE__ + 1 def #{association} return self.associated_forms['#{association}'] end METHOD end |
.delegate_attributes(*attributes) ⇒ Object
Delegates the list of attributes to the model, both readers and writers. If the attribute value passed is a hash and not a symbol, assumes it is a hash of one key, whose value is an array contained :reader, :writer, or both.
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'app/components/kadmin/form.rb', line 72 def delegate_attributes(*attributes) delegates = attributes.each_with_object([]) do |attribute, acc| case attribute when Hash key, value = attribute.first acc << key if value.include?(:reader) acc << "#{key}=" if value.include?(:writer) when Symbol, String acc.push(attribute, "#{attribute}=") else raise(ArgumentError, 'Attribute must be one of: Hash, Symbol, String') end end delegate(*delegates, to: :model) end |
Instance Method Details
#associated_forms ⇒ Object
105 106 107 108 109 110 111 112 |
# File 'app/components/kadmin/form.rb', line 105 def associated_forms return @associated_forms ||= begin self.class.associations.map do |name, form_class_name| form_class = form_class_name.constantize form_class.new(@model.public_send(name)) end end end |
#sanitize_for_mass_assignment(attributes) ⇒ Object
For now, we overload the method to accept all attributes. This is removed in Rails 5, so once we upgrade we can remove the overload.
61 62 63 |
# File 'app/components/kadmin/form.rb', line 61 def sanitize_for_mass_assignment(attributes) return attributes end |
#save ⇒ Object
143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'app/components/kadmin/form.rb', line 143 def save saved = false @model.class.transaction do saved = @model.save self.associated_forms.each do |_name, form| saved &&= form.save end raise ActiveRecord::Rollback unless saved end return saved end |
#save! ⇒ Object
157 158 159 160 161 162 163 164 165 166 167 |
# File 'app/components/kadmin/form.rb', line 157 def save! saved = false @model.class.transaction do saved = @model.save! self.associated_forms.each do |_name, form| saved &&= form.save! # no need to raise anything, save! will do so end end return saved end |
#to_model ⇒ Object
48 49 50 |
# File 'app/components/kadmin/form.rb', line 48 def to_model return @model end |