Skip to content

Creating new setting types

Vinicius Stock edited this page Feb 20, 2019 · 2 revisions

Creating new settings types

This is a quick guide to create new settings types in Sail. Adding a new setting type is pretty straight forward. There are 4 steps (some are not always needed).

  1. Create new class for type
  2. Add new type to Setting
  3. Add validations to Setting (optional)
  4. Add specific view input (optional)

Create new class for type

Create a new class for the desired type. Make sure to inherit from Type and override methods to_value and from if needed.

# frozen_string_literal: true

module Sail
  module Types
    # MyNewType
    #
    # Descriptive description of my
    # new type and why it exists.
    class MyNewType < Type
      def to_value
        # Logic for casting the database value appropriately
        # for the given type
        @setting.value # Cast this as desired
      end

      def from(value)
        # Logic for receiving values to be saved in the database
        # for the given type. Check types and do whatever
        # needed to properly store it in the database as a string.
        value.is_a?(::String) ? value : value.join(Sail.configuration.array_separator)
      end
    end
  end
end

Add new type to Setting

Add the new type at the end of the enum definition in Setting. Order matters due to backward compatibility with saved values in the database (always add at the end).

# app/models/sail/setting.rb

.
.
module Sail
  .
  .
  class Setting < ApplicationRecord
    .
    .
    enum cast_type: %i[integer string boolean range array float
                       ab_test cron obj_model date uri throttle
                       my_new_type].freeze
  end
end

Add validations to Setting

If the new type requires validation to prevent incorrect values from reaching the database, add them in Setting.

# app/models/sail/setting.rb

.
.
module Sail
  .
  .
  class Setting < ApplicationRecord
    .
    .
    validate :my_type_value_is_valid, if: -> { my_type? }
    .
    .
    private
  
    def my_type_value_is_valid
      if not_valid
        errors.add(:my_type_invalid, "Value is invalid for my type")
      end
    end
  end
end

Add specific view input

If the new type requires a different type of input in the dashboard (other than the usual input text), add another case in the following partial.

# app/views/sail/settings/_setting.html.erb
.
.
.
<% if setting.boolean? || setting.ab_test? %>
  <label class="switch">
    <input id="<%= "input_for_#{setting.name}" %>" type="checkbox" name="value" <%= setting.value == "true" ? "checked" : "" %>>
    <span class="slider round"></span>
  </label>
<% elsif setting.my_type? %>
  <input id="<%= "input_for_#{setting.name}" %>" type="some_type" value="<%= setting.value %>" name="value" class="my-css-class">
<% else %>
  <input id="<%= "input_for_#{setting.name}" %>" type="text" name="value" class="value-input" value="<%= setting.value %>"/>
<% end %>
Clone this wiki locally