【问题标题】:Nested JSON to Ruby class (with validation)嵌套 JSON 到 Ruby 类(带验证)
【发布时间】:2017-09-28 22:43:06
【问题描述】:

我有以下 JSON:

{
   "ordernumber":"216300001000",
   "datecreated":"2016-11-08T14:23:06.631Z",
   "shippingmethod":"Delivery",
   ...
   "customer":{
      "firstname":"Victoria",
      "lastname":"Validator"
   },
   "products":[
      {
         "sku":"ABC1",
         "price":"9.99"
      },
      ...
   ]
}

使用相应的 Ruby 类,包括验证器:

class Task
  include ActiveModel::Model
  include ActiveModel::Serializers::JSON

  validates ..., presence: true
  ...
end

class Product
  include ActiveModel::Model
  include ActiveModel::Serializers::JSON

  validates ..., presence: true
  ...
end

class Customer
  include ActiveModel::Model
  include ActiveModel::Serializers::JSON

  validates ..., presence: true
  ...
end

我想做的是将 JSON 序列化为 Ruby 类。问题是 Task 类得到了正确的初始化。但是像 Customer 和 Product 这样的嵌套类仍然是散列。 (一个任务有一个客户和多个产品)

例子:

json = %Q{{ "ordernumber":"216300001000", "datecreated":"2016-11-08T14:23:06.631Z", "shippingmethod":"Delivery", "customer":{ "firstname":"Victoria", "lastname":"Validator" }, "products":[ { "sku":"ABC1", "price":"9.99" } ] }}

task = Task.new()
task.from_json(json)

task.class
# => Task

task.products[0].class
# => Hash

如何使用 ActiveModel 执行此操作并验证嵌套的 JSON? (我没有使用 Rails)

【问题讨论】:

标签: json ruby activemodel


【解决方案1】:

据我所知,ActiveModel::Model 带来了验证和其他方便的东西,但它没有带来像这样的处理关联问题的工具。你必须自己执行他的行为。

首先,我会使用ActiveModel::Model 提供的内置初始化系统。然后我会定义products=customer= 来获取属性并初始化适当类的实例。并调用关联记录的验证。

class Task
  include ActiveModel::Model

  attr_reader :products, :customer

  # ...

  validate :associated_records_are_valid

  def products=(ary)
    @products = ary.map(&Product.method(:new))
  end

  def customer=(attrs)
    @customer = Customer.new(attrs)
  end

  private

  def associated_records_are_valid
    products.all?(&:valid?) && customer.valid?
  end
end

attributes = JSON.parse(json_str)
task = Task.new(attributes)

【讨论】:

    【解决方案2】:

    看这个话题:Is it possible to convert a JSON string to an object?。我现在不在电脑前发布代码,但我认为这个答案可以解决您的问题。

    【讨论】:

      猜你喜欢
      • 2020-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-10
      相关资源
      最近更新 更多