Home > Net >  In Rails 4, how do I reference an enum value when initializing my model?
In Rails 4, how do I reference an enum value when initializing my model?

Time:04-08

I’m using Rails 4.2. It is not an option to upgrade at this time. I have this model

class OrderItem < ApplicationRecord
    …
  enum type: { data: “Data”, product: “Product” }

How do I initialize my object by referencing my enum? I tried this

@order_item = OrderItem.new(
  order_item_params.merge(
    type: :product
  )
)
…
@order_item.save

But this results in the error

 NoMethodError:
   undefined method `safe_constantize' for :product:Symbol

CodePudding user response:

TLDR:

class OrderItem < ApplicationRecord
  self.inheritance_column = 'definitely_not_type'
  enum type: { data: "Data", product: "Product" }

type is the default for the inheritance_column in Rails. This column is mainly used for Single Table Inheritance. When it is present ActiveRecord will use the values in this column as the class for each row it fetches from the database.

So given the table animals with these values:

id | type   | name
------------------------
1  | Cat    | Mr Mittens
2  | Dog    | Laika
3  | Snake  | Snek

When you call Animal.all.map {|m| m.class} you will get [Cat, Dog, Snake]. Or at least you will if those contants actually exist.

If you're not actually using STI and want to use the name type you can just assign whatever you want to self.inheritance_column.

CodePudding user response:

I'd guess that you're running into an STI conflict, not an enum issue. Rails reserves the type column name for Single Table Inheritance (STI) and uses type to store the class name but you're trying to store a Symbol in type. ActiveRecord tries to convert the type value to a class, hence the complaint about not being able to call safe_constantize on your :product Symbol.

You could use a different name for your column or tell ActiveRecord to use a different name (presumably something you'd never use) for STI:

class OrderItem < ApplicationRecord
  self.inheritance_column = '_type'
  ...
end

I think self.inheritance_column = nil will also work in Rails4, I know nil works in Rails6 but I'm not certain about Rails4.

  • Related