-1

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
sergserg
  • 19,010
  • 36
  • 118
  • 175
  • Its probably because your edit is intiallizing the superclass, which has no validations. You are better off going with a validator method. Check out this answer: http://stackoverflow.com/questions/9229554/how-to-run-validations-of-sub-class-in-single-table-inheritance – ChrisBarthol May 16 '14 at 19:04
  • Just tried explicitly using `SettingNumerical` in the edit controller action and the validation still doesn't fire. Strange. – sergserg May 16 '14 at 19:18

1 Answers1

1

It's validates, not validate.
Try change to validates :numerical_value, presence: true

Doguita
  • 13,546
  • 3
  • 24
  • 35