将json解析为ruby对象

时间:2015-05-26 17:03:23

标签: ruby json

在ruby中,我如何将json解析为一组对象? 示例:我有2个班级:

class Person 
  attr_accessor :name, :address, :email, :address
end

并且:

class Address
  attr_accessor :street, :city, :state, :person
end

当我提出请求时,我得到以下json:

{
  "data": [
    {
      "id": 9111316,
      "name": "Mason Lee",
      "email": "normanodonnell@biospan.com",
      "address": {
        "state": "American Samoa",
        "street": "Cameron Court",
        "city": "Wakulla"
      }
    },
    {
      "id": 500019,
      "name": "Stella Weeks",
      "email": "hansenwhitfield@candecor.com",
      "address": {
        "state": "Nevada",
        "street": "Lake Street",
        "city": "Wacissa"
      }
    }
  ]
}

json应解析为Person数组 现在我正在做:

#json gem
require 'json'

#...
#parse the json and get the 'data'
parsed_json = JSON.parse json
json_data = parsed_json['data']

objects = Array.new
if json_data.kind_of?(Array)

  #add each person
  json_data.each { |data|
    current_person = Person.new
    data.each { |k, v|
      current_person.send("#{k}=", v)
    }
    objects.push(current_person)
  }
end

#return the array of Person
objects

我有很多像上面例子的对象,并且手动解析是不可取的。 有一种自动方式可以做到这一点吗?

通过"自动化方式&​​#34;我的意思是javajackson

ObjectMapper mapper = new ObjectMapper();
List<Person> myObjects = mapper.readValue(json, mapper.getTypeFactory().constructCollectionType(List.class, Person.class));

2 个答案:

答案 0 :(得分:3)

您可以使用哈希初始化Person:

$sql_category = "SELECT * FROM recipedia_categories";
$result_category = $db->query($sql_category);
    while ($row_category = $result_category->fetch_assoc()) {
        $ID_category = $row_category['ID'];
    }

${'category_' . '$row_category["ID"];'} = '';



if( isset( $_POST['category_' . '$row_category["ID"];'] ) ){
            ${'category_' . '$row_category["ID"];'} = $_POST['category_ID'];
        }

$sql = "INSERT INTO recipedia_recipies VALUES ('$category_ID')";

$sql_menu = "SELECT * FROM recipedia_categories ORDER BY category_name ASC";
$result_menu = $db->query($sql_menu);

如果要动态选择类,可以使用:

<?php
    while ( $row_menu = $result_menu->fetch_assoc() ) { 
?>
    <option name="category_<?=$row_menu['ID'];?>"><?=$row_menu['category_name'];?></option>
<?php
    }
?>

答案 1 :(得分:1)

为什么不自己制作方法呢?示例:

require 'json'
def parse_json_to_class_array(data,root_node,to_klass)
  json_data = JSON.parse(data)[root_node]
  if json_data.is_a?(Array)
    objects = json_data.map do |item|
      klass = to_klass.new
      item.each { |k,v| klass.public_send("#{k}=",v) }
      klass
    end
  end 
  objects ||= []
end

然后对于你的例子你可以这样称呼它

json ="{\"data\":[
          {\"id\":9111316,
           \"name\":\"Mason Lee\",
           \"email\":\"normanodonnell@biospan.com\",
           \"address\":{
              \"state\":\"American Samoa\",
              \"street\":\"Cameron Court\",
              \"city\":\"Wakulla\"
            }
          },
           {\"id\":500019,
            \"name\":\"Stella Weeks\",
            \"email\":\"hansenwhitfield@candecor.com\",
            \"address\":{
               \"state\":\"Nevada\",
               \"street\":\"Lake Street\",
               \"city\":\"Wacissa\"
             }
           }
         ]
       }"
class Person 
  attr_accessor :id, :name,:email, :address
end


parse_json_to_class_array(json,'data',Person) 
#=>[#<Person:0x2ede818 @id=9111316, @name="Mason Lee", @email="normanodonnell@biospan.com", @address={"state"=>"American Samoa", "street"=>"Cameron Court", "city"=>"Wakulla"}>, 
    #<Person:0x2ede7a0 @id=500019, @name="Stella Weeks", @email="hansenwhitfield@candecor.com", @address={"state"=>"Nevada", "street"=>"Lake Street", "city"=>"Wacissa"}>]

显然,您可以扩展此实现以支持单个对象,并覆盖Person#address=以执行相同的操作,并将地址Hash转换为Address对象,但这不是在你的例子中显示,所以我在答案中没有把它拿走这么远。

可以找到更具动态性的示例Here