ActiveModel 动态属性类型

如何解决ActiveModel 动态属性类型

是否可以决定哪种类型在运行时在 ActiveModel::Attributes 中强制转换属性我有以下代码

class DynamicType < ActiveModel::Type::Value
  def cast(value)
    value # here I don't have access to the underlying instance of MyModel
  end
end

class MyModel
  include ActiveModel::Model
  include ActiveModel::Attributes

  attribute :value,DynamicType.new
  attribute :type,:string
end

MyModel.new(type: "Integer",value: "12.23").value

我想根据 type 的指定值决定如何转换 value 属性。我用自定义类型尝试过,但结果是,在 #cast 方法中,您无权访问 MyModel 的底层实例(这也可能是一件好事,考虑将顾虑)

我还尝试使用 lambda 块,假设 ActiveModel 可能看到响应 #call 并在运行时调用此块的对象(它没有):

class MyModel
  include ActiveModel::Model
  include ActiveModel::Attributes

  attribute :value,->(my_model) {
    if my_model.type == "Integer"
      # some casting logic
    end
  }
  attribute :type,:string
end

# => throws error
# /usr/local/bundle/gems/activemodel-5.2.5/lib/active_model/attribute.rb:71:in `with_value_from_user': undefined method `assert_valid_value' for #<Proc:0x000056202c03cff8 foo.rb:15 (lambda)> (NoMethodError)

背景:type 来自一个 DB 字段,并且可以在其中包含各种类,这些类的作用远不止是转换一个整数。

我可以只做一个 def value 并在那里构建自定义逻辑,但我需要多次这样做,而且我还使用其他 ActiveModel 功能,如验证、嵌套属性......所以我必须注意自己整合。

所以也许有一种方法可以用 ActiveModel 本身来做到这一点。

解决方法

您将值作为字符串存储在数据库中,因此 ActiveRecord 会将其作为字符串检索。您将需要手动转换它。 Rails 提供了这些方法,我相信你很熟悉:

"1".to_i => to integer => 1
"foo.to_sym => to symbol => :foo
"1".to_f => to float => "1.0"
123.to_s => to string => "123"
(1..10).to_a => to array => [1,2,3,4,5,6,7,8,9,10]

然后在你的模型中你可以这样做:

def value
  case type
  when "Integer"
   value.to_i
  when "Float"
   value.to_f
  ...
end

这可以工作,但我发现这种方法有问题。您使用名称 type 对属性进行 decalre,您可能会遇到 Rails 的一些错误,抱怨 type 是 STI 的保留字,或者出现奇怪的错误,我建议您重命名它。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?