嵌套 JSON 到 Ruby class(有验证)
Nested JSON to Ruby class (with validation)
我有以下 JSON:
{
"ordernumber":"216300001000",
"datecreated":"2016-11-08T14:23:06.631Z",
"shippingmethod":"Delivery",
...
"customer":{
"firstname":"Victoria",
"lastname":"Validator"
},
"products":[
{
"sku":"ABC1",
"price":"9.99"
},
...
]
}
与相应的 Ruby classes 包括验证器:
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 class。问题是 Task class 已正确初始化。但是像 Customer 和 Product 这样的嵌套 classes 仍然是散列。 (一个任务有一个客户和多个产品)
示例:
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)
据我所知,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)
看这个话题:Is it possible to convert a JSON string to an object?。我现在不在电脑前 post 代码,但我认为这个答案可以解决你的问题。
我有以下 JSON:
{
"ordernumber":"216300001000",
"datecreated":"2016-11-08T14:23:06.631Z",
"shippingmethod":"Delivery",
...
"customer":{
"firstname":"Victoria",
"lastname":"Validator"
},
"products":[
{
"sku":"ABC1",
"price":"9.99"
},
...
]
}
与相应的 Ruby classes 包括验证器:
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 class。问题是 Task class 已正确初始化。但是像 Customer 和 Product 这样的嵌套 classes 仍然是散列。 (一个任务有一个客户和多个产品)
示例:
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)
据我所知,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)
看这个话题:Is it possible to convert a JSON string to an object?。我现在不在电脑前 post 代码,但我认为这个答案可以解决你的问题。