使用我当前的项目,我收到一个大的JSON文件,我正在解析并存储到我的数据库中。问题是我觉得我正在以非常低效的方式构建我的数据库。
JSON示例:
{
first_name: "John",
records: {
ids: [110, 725, 2250],
count: [1, 1, 6]
},
items: {
top: {
title: "My top",
values: { value: [51, 50, 70] }
},
middle: {
title: "Middle Stuff",
values: { value: [51] }
},
},
values: {
health: 100,
strength: 250,
mana: 50
}
}
正如您所看到的,JSON相当复杂,具有嵌套的对象。
在构建它时,我从主对象(user
)开始,然后慢慢开始添加更多对象。 Values
非常简单,因此我将其添加为另一个表格,并仅提及user_id
。
然后我做records
,这有点复杂,但有效。但是,我非常担心最嵌套的部分,可能是5个以上的物体。我觉得我不应该有一个简单值的整列行。
改善这一点的最佳方法是什么?我应该以某种方式处理数据并以不同方式存储它吗?
感谢您的帮助。
答案 0 :(得分:0)
// JSON回复
{
"name": "John Smith",
...
"progression": {
"levels": [{
"name": "Level 1",
"bosses": [
{
"name": "Boss 1",
"difficultyCompleted": "Hard"
},
{
"name": "Boss 2",
"difficultyCompleted": "Hard"
}]
},{
"name": "Level 2",
"bosses": [
{
"name": "Boss 3",
"difficultyCompleted": "Normal"
},
{
"name": "Boss 4",
"difficultyCompleted": "Easy"
}]
}
}
}
在此示例JSON中,用户已完成每个boss的几个层。我最初想要做的是创建模型和表格,但这似乎不仅在记忆中会浪费,而且还需要更长时间来获取Boss 4
的当前进度。
示例:
User has_one Progression.
Progression has_one Levels.
Levels has_many Dungeons.
Dungeons has_many bosses.
我所做的是尝试将bosses
压缩为单个字段,并在运行时转换JSON。
所以,我的结构就是这样。
User has_one Progression.
Progression has_many Dungeons.
型号: // Progression.rb
class Progression < ApplicationRecord
has_many :dungeons
def self.initialize(params={})
params = params['levels']
prog = Progression.new()
params.each do |dungeon|
prog.dungeons.append( Dungeon.initialize( dungeon ) )
end
return prog
end
end
// Dungeon.rb
class Dungeon < ApplicationRecord
belongs_to :progression
def self.initialize(params={})
Dungeon.new(params.reject { |k| !Dungeon.attribute_method?(k) }) # Used to ignore any unused parameters that don't exist on the model.
end
# To convert `bosses` from JSON into a hash for easy use.
def get_bosses
JSON.parse bosses.gsub( '=>', ':' )
end
end
迁移: // xxxxxx_create_progression.rb
class CreateProgression < ActiveRecord::Migration[5.0]
def change
create_table :progressions do |t|
t.integer :character_id
end
create_table :dungeons do |t|
t.integer :character_id
t.integer :progression_id
t.string :name
t.text :bosses
end
add_index :progressions, :character_id
add_index :dungeons, :progression_id
end
end
现在,当用户更新以获取其进展时,我可以设置他们的进展。
// users_controller.rb
def update_progression
progression = ... fetched from the response
@user.progression = Progression.initialize(progression)
end
之后全部保存给用户,您现在可以通过以下方式获取进度:
<% user.progression.dungeons.each do |dungeon| %>
<%= dungeon.name %>
<% end %>
这个解决方案似乎是一个不错的组合,但我有点担心解析JSON。它可能会变得太多,但我必须继续观察它。任何其他想法或改进都将大大改变。