I have a simple use case where my users will save settings on the application. There are different setting types: numerical, price, and date intervals.
create_table "settings", force: true do |t|
t.string "type"
t.decimal "price_value", precision: 8, scale: 2
t.integer "numerical_value", default: 35
t.date "start_date_value", default: '2014-01-01'
t.date "end_date_value", default: '2014-12-31'
t.datetime "created_at"
t.datetime "updated_at"
t.string "name"
end
----
class Setting < ActiveRecord::Base
end
class SettingDateInterval < Setting
validate :start_date_value, :end_date_value, presence: true
end
class SettingNumerical < Setting
validate :numerical_value, presence: true
end
class SettingPrice < Setting
validate :price_value, presence: true
end
The type
field in this case saves the name of the Setting subclass name automatically.
In my edit controller actions, I can still save a SettingPrice
with an empty :price_value
or a SettingNumerical
with an empty :numerical_value
- the validations are not running.
= simple_form_for @setting, url: setting_path, html: { class: 'panel form-horizontal' } do |f|
.panel-body
= render 'shared/form_errors', resource: @setting
.form-group
= f.label :name, class: 'col-sm-2 control-label'
.col-sm-10
= f.input_field :name, class: 'form-control', disabled: true
- if @setting.type == 'SettingNumerical'
.form-group
= f.label :numerical_value, class: 'col-sm-2 control-label', label: "Value"
.col-sm-10
= f.input_field :numerical_value, class: 'form-control'
- elsif @setting.type == 'SettingPrice'
.form-group
= f.label :price_value, class: 'col-sm-2 control-label', label: "Amount"
.col-sm-10
.input-group
span.input-group-addon $
= f.input_field :price_value, class: 'form-control'
- else
.form-group
= f.label :start_date_value, class: 'col-sm-2 control-label', label: "Starting Date:"
.col-sm-10
= f.input_field :start_date_value, class: 'form-control'
.form-group
= f.label :end_date_value, class: 'col-sm-2 control-label', label: "Ending Date:"
.col-sm-10
= f.input_field :end_date_value, class: 'form-control'
.form-group style="margin-bottom: 0;"
.col-sm-offset-2.col-sm-10
= f.button :submit, 'Submit', class: 'btn btn-primary'
def edit
@setting = Setting.find(params[:id])
end
def update
successfully_updated = if !params[:setting_numerical].nil?
@setting = SettingNumerical.find(params[:id])
@setting.update(setting_numerical_params)
elsif !params[:setting_price].nil?
@setting = SettingPrice.find(params[:id])
@setting.update(setting_price_params)
else
@setting = SettingDateInterval.find(params[:id])
@setting.update(setting_date_interval_params)
end
if successfully_updated
flash[:success] = 'Setting was updated successfully.'
redirect_to settings_path
else
flash[:error] = "Couldn't update the setting."
render action: 'edit'
end
end