2014-05-22 25 views
1

目前我有不同的as_json方法行爲。這就是爲什麼我的規格不能成功運行。as_json的不同行爲

User.first.as_json 
# => {"username"=>"Joe", "created_at"=>Thu, 24 Apr 2014 09:41:17 UTC +00:00 } 

User.first.created_at.as_json 
# => "2014-04-24T09:41:17Z" 

在我的模型我添加了一個serializable_hash方法來限制JSON和XML領域:

def serializable_hash(options={}) 
    super(only: [:username, :created_at]) 
end 

我的RSpec的行爲測試,這導致了錯誤的情況如下:

it "response in json format" do 
    expect(json).to eq assigns[:user].as_json 
end 

錯誤只提及兩個時間戳不相等:

-"created_at" => Thu, 24 Apr 2014 09:41:17 UTC +00:00, 
+"created_at" => "2014-04-24T09:41:17Z", 

如何在第一行設置成員對象的日期時間格式?

感謝您的幫助。

斯特芬

+0

你的'as_json'方法是什麼樣的?你是說你定製它嗎? – pdobb

+0

@pdobb:我在我的模型中添加了serializable_hash方法。但是這隻與在json輸出中設置我喜歡的字段有關。 – sts

回答

0

,因爲它們是不同的序列化,根據對象的類型調用由as_json正在發生。

時間as_json一個正在呼叫xmlschema並且這被返回像格式:%Y-%間 - %的dT%H:%M:%S Z.請按照源代碼在這裏(使用PRY):

pry(main)> show-source User.first.validated_at.as_json 
def as_json(options = nil) 
    if ActiveSupport::JSON::Encoding.use_standard_json_time_format 
    xmlschema 
    else 
    %(#{time.strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)}) 
    end 
end 

pry(main)> show-source User.first.validated_at.xmlschema 
def xmlschema(fraction_digits = 0) 
    fraction = if fraction_digits > 0 
    (".%06i" % time.usec)[0, fraction_digits + 1] 
    end 

    "#{time.strftime("%Y-%m-%dT%H:%M:%S")}#{fraction}#{formatted_offset(true, 'Z')}" 
end 

儘管ActiveRecord的as_json呼籲serializable_hash併爲每個字段做最後一to_s即返回這樣的格式:%Y-%間%d%H:%M:%S UTC

pry(main)> show-source User.first.as_json 
def as_json(options = nil) 
    root = include_root_in_json 
    root = options[:root] if options.try(:key?, :root) 
    if root 
    root = self.class.model_name.element if root == true 
    { root => serializable_hash(options) } 
    else 
    serializable_hash(options) 
    end 
end 

pry(main)> show-source User.first.serializable_hash 
def serializable_hash(options = nil) 
    options = options.try(:clone) || {} 

    options[:except] = Array.wrap(options[:except]).map { |n| n.to_s } 
    options[:except] |= Array.wrap(self.class.inheritance_column) 

    super(options) 
end 

pry(main)> show-source User.first.validated_at.to_s 
def to_s(format = :default) 
    if format == :db 
    utc.to_s(format) 
    elsif formatter = ::Time::DATE_FORMATS[format] 
    formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter) 
    else 
    "#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}" # mimicking Ruby 1.9 Time#to_s format 
    end 
end 
+0

Thanx @Rafa。有沒有辦法將兩種格式設置爲相同?我發現'class ActiveSupport :: TimeWithZone'將幫助我進行第二個例子。第一個像這樣的東西? – sts

+0

這取決於你想得到什麼樣的輸出。如果你想要一個JSON,你可以在兩者中執行'.to_json',它將以相同的格式返回時間。 –

+0

'.to_json'不是我想要的,因爲它只反映json輸出。用'serializable_hash'我可以設置json和xml的字段。 – sts