从其json表示中获取IPAddr实例 [英] Get IPAddr instance from its json representation

查看:133
本文介绍了从其json表示中获取IPAddr实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

$ p

上下文:



我正在使用使用 draftsman gem的Rails应用程序。基本上,当对数据库中的记录进行更改时,并且红宝石模型 has_drafts ,而不是立即更改记录,更改草案和生成的记录保存在草稿表中,直到一个发布!。然后对实际记录进行更改。相当整齐:)



草稿表包含允许在postgres表中的json列中进行更改的对象。



我也在使用Devise,我的用户模型使用可追踪模块,其中包含一个 current_sign_in_ip 以及列类型 inet last_sign_in_ip



问题:



inet 在我的用户表中键入列,以及其余的用户对象,正在存储在由 draftsman gem创建的草稿表中,单个json列中名为物体。在这种情况下,由于以下原因: reify 该对象不成功,因为以下原因: IPAddr 实例有一个json表示 IPAddr 类不能察觉。例如,ruby中的 IPAddr 实例响应 to_json ,这给我看起来像这样: \ family\ :2,\ addr\ :2130706433,\ mask_addr\ :4294967295}。这些实例也响应 to_s ,并给我这样的东西:127.0.0.1。不幸的是, IPAddr 类似乎不知道如何把自己从json从我可以告诉的东西:



< pre class =lang-rb prettyprint-override> [277,286] in /home/jake/.rvm/gems/ruby-2.2.1/bundler/gems/draftsman-1bd3c797d540/lib/ draftsman / model.rb
277:data = {
278::item => self,
279::whodunnit => Draftsman.whodunnit,
280::object => object_attrs_for_draft_record
281:}
=> 282:data = merge_metadata_for_draft(data)
283:
284:#如果已经有草稿,请更新。
285:if send(self.class.draft_association_name).present?
286:data [:object_changes] = changes_for_draftsman如果track_object_changes_for_draft?

(byebug)data [:object] ['current_sign_in_ip']
#< IPAddr:IPv4:127.0.0.1/255.255.255.255>
(byebug)data [:object] ['current_sign_in_ip']。to_json
{\family\:2,\add​​r\:2130706433,\mask_addr\\ \\:4294967295}

(byebug)IPAddr.new(data [:object] ['current_sign_in_ip']。to_s)
#< IPAddr:IPv4:127.0.0.1/255.255 .255.255>
(byebug)IPAddr.new(data [:object] ['current_sign_in_ip']。to_json)
*** IPAddr :: InvalidAddressError异常:无效地址

nil
(byebug)

我想把这个问题发布给StackOverflow会引起这个问题的一些注意,我还在 Draftsman 问题 $ c> github页面,如果需要任何其他信息。

解决方案

不知道这是否有帮助,但如果您阅读我的评论d_ethier的答案您可以看到, IPAddr 并不知道有关JSON的任何内容。



但是,您可以将猴子修补要理解这样的JSON:

  require'active_model'
require'active_support'
require'active_support / core_ext'
require'ipaddr'

class IPAddr
include ActiveModel :: Serializers :: JSON

attr_accessor:addr,:mask_addr,:family

def attributes =(hash)
hash.each do | key,value |
send(#{key} =,value)
end
end

定义属性
instance_values
end
end

pi = IPAddr.new('127.0.0.1')
pj = i.to_json
p IPAddr.new.from_json(j)

输出:

 #< IPAddr: IPv4的:127.0.0.1/255.255.255.255> 
{\family\:2,\add​​r\:2130706433,\mask_addr\:4294967295}
#< IPAddr:IPv4:127.0。 0.1 / 255.255.255.255>

资料来源:

http://apidock.com/rails/ActiveModel/Serializers/JSON/from_json


How can I get back an IPAddr instance from its json representation?

Context:

I'm working on a Rails application that uses the draftsman gem. Essentially, when one makes a change to a record in the database and that ruby model has_drafts, instead of making the change to the record right away, a draft of the changes and the resulting record is saved in the drafts table until one publish!es that draft. Then the changes are made to the actual record. Pretty neat :)

The drafts table holds the object that would result from allowing the changes to happen in a json column in a postgres table.

I'm also using Devise and my user model uses the trackable module, which includes a current_sign_in_ip as well as a last_sign_in_ip of column type inet.

Problem:

inet type columns in my user table, as well as the rest of the User object, are being stored in the drafts table created by the draftsman gem in a single json column called object. reifying the object from its draft does not succeed in this case because of the following reason: IPAddr instances have a json representation that the IPAddr class is incapable of perceiving. For example, IPAddr instances in ruby respond to to_json, which gives me something that looks like this: "\"family\":2,\"addr\":2130706433,\"mask_addr\":4294967295}". These instances also respond to to_s and give me something like this: "127.0.0.1". Unfortunately, the IPAddr class doesn't seem to know how to bring itself back from json from what I can tell:

[277, 286] in /home/jake/.rvm/gems/ruby-2.2.1/bundler/gems/draftsman-1bd3c797d540/lib/draftsman/model.rb
   277:               data = {
   278:                 :item      => self,
   279:                 :whodunnit => Draftsman.whodunnit,
   280:                 :object    => object_attrs_for_draft_record
   281:               }
=> 282:               data = merge_metadata_for_draft(data)
   283: 
   284:               # If there's already a draft, update it.
   285:               if send(self.class.draft_association_name).present?
   286:                 data[:object_changes] = changes_for_draftsman if track_object_changes_for_draft?

(byebug) data[:object]['current_sign_in_ip']
#<IPAddr: IPv4:127.0.0.1/255.255.255.255>
(byebug) data[:object]['current_sign_in_ip'].to_json
"{\"family\":2,\"addr\":2130706433,\"mask_addr\":4294967295}"

(byebug) IPAddr.new(data[:object]['current_sign_in_ip'].to_s)
#<IPAddr: IPv4:127.0.0.1/255.255.255.255>
(byebug) IPAddr.new(data[:object]['current_sign_in_ip'].to_json)
*** IPAddr::InvalidAddressError Exception: invalid address

nil
(byebug) 

I figured posting this question to StackOverflow would get some attention to this issue, but I also submitted a github issue on the Draftsman github page if any other information is needed.

解决方案

Not sure if this helps, but if you read my comment below d_ethier's answer you can see that IPAddr doesn't really know anything about JSON.

However you can monkey patch it to understand JSON like so:

require 'active_model'
require 'active_support'
require 'active_support/core_ext'
require 'ipaddr'

class IPAddr
  include ActiveModel::Serializers::JSON

  attr_accessor :addr, :mask_addr, :family

  def attributes=(hash)
    hash.each do |key, value|
      send("#{key}=", value)
    end
  end

  def attributes
    instance_values
  end
end   

p i = IPAddr.new('127.0.0.1')
p j = i.to_json
p IPAddr.new.from_json(j)

Output:

#<IPAddr: IPv4:127.0.0.1/255.255.255.255>
"{\"family\":2,\"addr\":2130706433,\"mask_addr\":4294967295}"
#<IPAddr: IPv4:127.0.0.1/255.255.255.255>

Source:
http://apidock.com/rails/ActiveModel/Serializers/JSON/from_json

这篇关于从其json表示中获取IPAddr实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆