2014-05-22 2 views
1

Actuellement, j'ai un comportement différent de la méthode as_json. C'est pourquoi mes spécifications ne fonctionnent pas correctement.Comportement différent de 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" 

Dans mon modèle, j'ajouté une méthode de serializable_hash pour limiter les champs JSON et xml:

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

Mon comportement rspec contrôle les éléments suivants qui se traduit par une erreur:

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

L'erreur mentionne seulement que les deux horodatages ne sont pas égaux:

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

Comment puis-je définir le format de l'heure de la date pour l'objet membre dans la première ligne?

Merci pour votre aide.

Steffen

+0

À quoi ressemble votre méthode 'as_json'? Êtes-vous en train de dire que vous l'avez personnalisé? – pdobb

+0

@pdobb: J'ai ajouté la méthode serializable_hash que j'ai dans mon modèle. Mais ceci n'est pertinent que pour définir les champs que j'aime dans une sortie json. – sts

Répondre

0

Ce qui se passe parce qu'ils sont différents serializers, en fonction du type d'objet appelle as_json de.

Le temps as_json appelle un xmlschema et ce renvoie un format comme:% Y-% m-% dT% H:% M:% S Z. S'il vous plaît suivre le code source ici (en utilisant 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 

Alors que le ActiveRecordas_json appelle serializable_hash et pour chaque domaine fait enfin un to_s qui retourne ce genre de format:% Y-% m-% 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. Existe-t-il un moyen de définir les deux formats au même niveau? J'ai découvert qu'une 'classe ActiveSupport :: TimeWithZone' m'aidera pour le deuxième exemple. Quelque chose comme ça pour le premier? – sts

+0

Cela dépend de ce que vous voulez obtenir en sortie. Si vous voulez un JSON vous pouvez faire '.to_json' dans les deux et il retournera les temps dans le même format. –

+0

'.to_json' n'est pas ce que je veux car il ne reflète que la sortie de json. Avec 'serializable_hash' je peux définir les champs pour json et xml. – sts

Questions connexes