Home > Software engineering >  Why is Rails ignoring validation when I run create
Why is Rails ignoring validation when I run create

Time:11-07

The simplified example is that I have several classes inheriting from an Asset class, which is an ActiveRecord model. When I use create or create! on one of the subclasses both the db layer and ActiveRecord layer validations for one field are ignored.

The Asset table has a type field with null: false, the Asset model has validates_presence_of :type and also has attribute :type, default: self.name.

If I use new on a subclass, such as Item, it behaves as expected, I get an Item with the type field set to "Item". If I use create or create! with valid attributes, the defaults are not applied, validation is ignored and I get a persisted record with a type field of nil.

What's odd is that other validations are respected. If I try creating a new Item without a name attribute, validates_presence_of :name properly raises a validation error.

Here's some pared down code snippets for reference:

class CreateAssets < ActiveRecord::Migration[6.0]
  def change
    create_table :assets do |t|
      t.string :type, null: false
      t.string :name
      # ...
    end
  end
end
class Asset < ApplicationRecord
  enum type: {
    Item: :Item,
    Accessory: :Accessory,
    Component: :Component,
    Consumable: :Consumable,
  }

  attribute :type, default: self.name

  validates_presence_of :name
  validates_presence_of :type
end
class Item < Asset
  # ...
end
i = Item.create({ ... })
i.type
#nil
i.persisted?
#true
i.valid?
#false
i = Item.new({ ... })
i.type
#"Item"
i.valid?
#true

CodePudding user response:

'type' is a reserved column name in ActiveRecord because it is used to indicate Single Table Inheritance (STI) . If you are not intending to use STI you should pick a different column name otherwise the STI behaviors will interfere with what you're trying to do here.

  • Related