Rails find_or_create_by添加强制转换为哈希值json类型属性?

问题描述 投票:0回答:1

我有一个:extra_fields列的模型是:jsonb数据类型,我想在列中添加attr哈希值,如下所示,但我不确定在这里抛出哈希值'数据类型的语法,如果不在这里什么的是否是投射哈希值数据的最佳做法?

      instance = Model.find_or_create_by(ref_id: hash[:ref_id]) do |a|
          a.extra_fields = {

            'attr1' : hash[:attr1], <-- //possible to cast type here ie ::type ?
            'attr2' : hash[:attr2]  <--

          }
        instance.save!
      end

额外奖励:我如何将哈希值转换为类型:decimal:string:boolean:date

ruby-on-rails json activerecord hash casting
1个回答
2
投票

Rails / Rack中的所有传入参数都是字符串。除了仍然有字符串作为值的数组/哈希参数之外。将参数传递给模型时,Rails会执行实际的转换。

您可以使用.to_x方法将字符串转换为Ruby中的任何其他类型:

irb(main):006:0> "1.23".to_f
=> 1.23
irb(main):007:0> "1.23".to_d
=> #<BigDecimal:7ff7dea40b68,'0.123E1',18(18)>
irb(main):008:0> 1.23.to_s
=> "1.23"
irb(main):008:0> 1.23.to_i
=> 1

Boolean cast是一个Rails功能。你可以这样做:

# Rails 5
ActiveModel::Type::Boolean.new.cast(value) 
ActiveModel::Type::Boolean.new.cast("true") # true
ActiveModel::Type::Boolean.new.cast("t") # true 
ActiveModel::Type::Boolean.new.cast("false") # false
ActiveModel::Type::Boolean.new.cast("f") # false
# This is somewhat surprising
ActiveModel::Type::Boolean.new.cast("any arbitrary string") # true


# Rails 4.2
ActiveRecord::Type::Boolean.new.type_cast_from_database(value)

# Rails 4.1 and below
ActiveRecord::ConnectionAdapters::Column.value_to_boolean(value)

请注意,这与!!!完成的Ruby布尔强制非常不同。

irb(main):008:0> !!"false"
(irb):8: warning: string literal in condition
=> true

在Ruby中除了nil和false之外的所有内容都是正确的。

日期有点复杂。默认的Rails日期输入使用多参数发送日期的每个部分(年,月,日)以及从这些输入构造日期的特殊设置器。

Processing by PeopleController#create as HTML
  Parameters: { "person"=>{"birthday(1i)"=>"2019", "birthday(2i)"=>"2", "birthday(3i)"=>"16"}, ...}

您可以通过以下方式从这些参数构造日期:

date_params = params.fetch(:person).permit("birthday")
Date.new(*date_params.values.map(&:to_i))

什么是投射哈希值数据的最佳做法?

这里没有最好的做法。您应该思考的是使用JSON列。由于您似乎希望将某种模式应用于数据,因此实际创建单独的表和模型可能是个好主意。毕竟你使用的是关系数据库。

JSON列非常适合解决一些复杂问题,如键/值表或存储原始JSON数据,但在建模数据时,它们不应该是您的首选。

请参阅PostgreSQL anti-patterns: Unnecessary json/hstore dynamic columns以获取有关该主题的详细信息。

© www.soinside.com 2019 - 2024. All rights reserved.