在我的MySQL数据库中,有一个名为query_data的字段被定义为text。
在我的模型中,我将这个字段定义为serialize :query_data, JSON。
我要保存和检索JSON格式如下:
{:items => [
{:id => 1},
{:id => 2},
{:id => 3}
]}我有一个包含对象数组的集合(在本例中称为items)。
我想知道,添加或删除项目的最佳方法是什么。
示例:从我的项目列表中删除{:id => 2}并添加`{:id => 4}
发布于 2019-03-26 20:09:27
基于@veridian-dynamics (感谢您的帮助!)这是我所做的。
型号:
class MyModel < ApplicationRecord
serialize :item_data, JSON
end控制器:
class ItemController < ApplicationController
before_action :authenticate_user!
def add_item
begin
mymodel = MyModel.find_or_create_by(id: param[:model_id])
if mymodel .item_data.blank?
item = {:items => []}
else
item = mymodel.item_data.deep_symbolize_keys
end
bookmark_exist = item[:items].any? {|i| i[:id] == params[:id]}
if !bookmark_exist
item[:items] = item[:items ].append({id: params[:id]}) # adding a new item
end
mymodel.item_data = item
mymodel.save
return render :json => item, :status=> 200
rescue Exception => e
return render :json =>{:errors=>e.message}, :status=> 400
puts "ERROR: #{e.message}"
end
end
def delete_item
begin
mymodel = MyModel.find_by(id: params[:model_id])
if mymodel.present? && mymodel.item_data.present?
item = mymodel.item_data.deep_symbolize_keys
item[:items] = (item[:items].select { |itm| itm[:id] != params[:id] }) # remove an item
mymodel.item_data = item
mymodel.save
return render :json => item, :status=> 200
end
rescue Exception => e
return render :json =>{:errors=>e.message}, :status=> 400
puts "ERROR: #{e.message}"
end
end
end发布于 2019-03-23 02:00:34
Ruby on Rails有一些很好的方法可以在JSON和Ruby之间无缝转换。
thing = {:items => [
{:id => 1},
{:id => 2},
{:id => 3}
]}
thing.to_json # "{\"items\":[{\"id\":1},{\"id\":2},{\"id\":3}]}"thing.to_json本质上是序列化程序中正在发生的事情。如果你想让它们回到Ruby,你可以这样做:
@items = @thing.query_data
JSON.parse(@items) # "items"=>[{"id"=>1}, {"id"=>2}, {"id"=>3}]}现在我们可以很容易地在这两者之间切换,让我们只使用Ruby语法来处理添加和删除键。
thing = {:items => [
{:id => 1},
{:id => 2},
{:id => 3}
]}
thing[:items] = thing[:items].append({:id => 4}) # adding a new item
thing[:items] = thing[:items].select { |item| item[:id] != 2 } # removing an item发布于 2019-03-23 02:36:16
第一: serialize的第二个参数应该是存储在字段中的对象的类。您应该使用serialize :query_data, Hash。
除此之外,实际上还没有任何处理序列化数据的最佳实践。这在很大程度上取决于你的数据结构。您可能会问:“从散列中添加或删除项的最佳方法是什么?”
但是,由于这是一个散列,所以您应该确保将dirty attributes放在心上。如果你要做类似这样的事情:
items = my_model.query_data[:items]
items.reject! {|item| item[:id] == 2}
items += {id: 4}那么模型就不会知道query_data发生了变化,应该在保存时进行更新。
my_model.changed?
# => false
my_model.save
# Won't actually save changes to db.要避免这种情况,您可以:
A)确保您只直接设置my_model.query_data
B)在更改该字段后显式调用my_model.query_data_will_change!,以便在保存时正确更新。
https://stackoverflow.com/questions/55305116
复制相似问题