在 Rails 4 中,初始化模型时如何引用枚举值?

发布于 2025-01-19 20:34:14 字数 428 浏览 5 评论 0原文

我正在使用Rails 4.2。此时,这不是升级的选择。我有这个模型

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

如何通过引用枚举来初始化对象?我尝试过,

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

但这导致了错误

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浪漫之都 2025-01-26 20:34:14

TLDR:

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

type 是Rails 中inheritance_column 的默认值。该列主要用于单表继承。当它存在时,ActiveRecord 将使用此列中的值作为它从数据库中获取的每一行的类。

因此,给定表 animals 具有以下值:

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

当您调用 Animal.all.map {|m| m.class} 你会得到 [Cat, Dog, Snake]。或者至少如果这些内容确实存在的话你会的。

如果您实际上没有使用 STI 并且想要使用名称 type,您可以将您想要的任何内容分配给 self.inheritance_column

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.

陌伤浅笑 2025-01-26 20:34:14

我猜您遇到的是 STI 冲突,而不是 enum 问题。 Rails 为单表继承 (STI) 保留 type 列名称,并使用 type 存储类名,但您尝试在 type< 中存储符号/代码>。 ActiveRecord 尝试将 type 值转换为类,因此抱怨无法在 :product 符号上调用 safe_constantize

您可以为您的列使用不同的名称,或者告诉 ActiveRecord 对 STI 使用不同的名称(大概是您从未使用过的名称):

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

我认为 self.inheritance_column = nil 也适用于 Rails4,我知道 nil 在 Rails6 中有效,但我不确定 Rails4 是否有效。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文