Objet Rails à hacher

J’ai l’object suivant qui a été créé

@post = Post.create(:name => 'test', :post_number => 20, :active => true) 

Une fois cela sauvegardé, je veux pouvoir ramener l’object à un hash, par exemple en faisant quelque chose comme:

 @object.to_hash 

Comment est-ce possible de l’intérieur des rails?

Si vous recherchez uniquement des atsortingbuts, vous pouvez les obtenir par:

 @post.atsortingbutes 

Dans la version la plus récente de Rails (vous ne pouvez pas dire laquelle), vous pouvez utiliser la méthode as_json :

 @post = Post.first hash = @post.as_json puts hash.pretty_inspect 

Va sortir:

 { :name => "test", :post_number => 20, :active => true } 

Pour aller un peu plus loin, vous pouvez remplacer cette méthode afin de personnaliser la manière dont vos atsortingbuts apparaissent, en faisant quelque chose comme ceci:

 class Post < ActiveRecord::Base def as_json(*args) { :name => "My name is '#{self.name}'", :post_number => "Post ##{self.post_number}", } end end 

Ensuite, avec la même instance que ci-dessus, va sortir:

 { :name => "My name is 'test'", :post_number => "Post #20" } 

Cela signifie bien sûr que vous devez spécifier explicitement quels atsortingbuts doivent apparaître.

J’espère que cela t’aides.

MODIFIER :

Aussi, vous pouvez vérifier le bijou Hashifiable .

 @object.as_json 

as_json a un moyen très flexible pour configurer un object complexe en fonction des relations de modèle

EXEMPLE

La campagne modèle appartient à la boutique et comporte une liste

La liste de modèles a beaucoup de list_tasks et chacun de list_tasks a beaucoup de commentaires

Nous pouvons obtenir un json qui combine toutes ces données facilement.

 @campaign.as_json( { except: [:created_at, :updated_at], include: { shop: { except: [:created_at, :updated_at, :customer_id], include: {customer: {except: [:created_at, :updated_at]}}}, list: { except: [:created_at, :updated_at, :observation_id], include: { list_tasks: { except: [:created_at, :updated_at], include: {comments: {except: [:created_at, :updated_at]}} } } }, }, methods: :tags }) 

Méthodes de notification :: les balises peuvent vous aider à joindre tout object supplémentaire n’ayant pas de relations avec d’autres. Il vous suffit de définir une méthode avec des balises de nom dans la campagne modèle. Cette méthode devrait renvoyer tout ce dont vous avez besoin (par exemple, Tags.all)

Documentation officielle pour as_json

Il y a d’excellentes suggestions ici.

Je pense qu’il est intéressant de noter que vous pouvez traiter un modèle ActiveRecord comme un hash comme ceci:

 @customer = Customer.new( name: "John Jacob" ) @customer.name # => "John Jacob" @customer[:name] # => "John Jacob" @customer['name'] # => "John Jacob" 

Par conséquent, au lieu de générer un hachage des atsortingbuts, vous pouvez utiliser l’object lui-même en tant que hachage.

Vous pouvez obtenir les atsortingbuts d’un object modèle renvoyés sous forme de hachage en utilisant soit

 @post.atsortingbutes 

ou

 @post.as_json 

as_json vous permet d’inclure des associations et leurs atsortingbuts ainsi que de spécifier les atsortingbuts à inclure / exclure (voir la documentation ). Cependant, si vous n’avez besoin que des atsortingbuts de l’object de base, l’parsing comparative de mon application avec ruby ​​2.2.3 et rails 4.2.2 montre que les atsortingbutes nécessitent moins de la moitié de temps que as_json .

 >> p = Problem.last Problem Load (0.5ms) SELECT "problems".* FROM "problems" ORDER BY "problems"."id" DESC LIMIT 1 => # >> >> p.atsortingbutes => {"id"=>137, "enabled"=>true, "created_at"=>Fri, 19 Feb 2016 11:20:28 UTC +00:00, "updated_at"=>Fri, 26 Feb 2016 07:47:34 UTC +00:00} >> >> p.as_json => {"id"=>137, "enabled"=>true, "created_at"=>Fri, 19 Feb 2016 11:20:28 UTC +00:00, "updated_at"=>Fri, 26 Feb 2016 07:47:34 UTC +00:00} >> >> n = 1000000 >> Benchmark.bmbm do |x| ?> x.report("atsortingbutes") { n.times { p.atsortingbutes } } ?> x.report("as_json") { n.times { p.as_json } } >> end Rehearsal ---------------------------------------------- atsortingbutes 6.910000 0.020000 6.930000 ( 7.078699) as_json 14.810000 0.160000 14.970000 ( 15.253316) ------------------------------------ total: 21.900000sec user system total real atsortingbutes 6.820000 0.010000 6.830000 ( 7.004783) as_json 14.990000 0.050000 15.040000 ( 15.352894) 

Vous pouvez certainement utiliser les atsortingbuts pour renvoyer tous les atsortingbuts, mais vous pouvez append une méthode d’instance à Post, l’appeler “to_hash” et lui renvoyer les données que vous souhaitez dans un hachage. Quelque chose comme

 def to_hash { name: self.name, active: true } end 

Je ne sais pas si c’est ce dont vous avez besoin, mais essayez ceci dans la console ruby:

 h = Hash.new h["name"] = "test" h["post_number"] = 20 h["active"] = true h 

évidemment, cela vous renverra un hachage dans la console. Si vous voulez retourner un hachage dans une méthode – au lieu de simplement “h” essayez d’utiliser “return h.inspect”, quelque chose de similaire à:

 def wordcount(str) h = Hash.new() str.split.each do |key| if h[key] == nil h[key] = 1 else h[key] = h[key] + 1 end end return h.inspect end 

Ma solution:

 Hash[ post.atsortingbutes.map{ |a| [a, post[a]] } ] 

La réponse de Swanand est géniale.

Si vous utilisez FactoryGirl, vous pouvez utiliser sa méthode de génération pour générer l’atsortingbut hash sans l’ id clé. par exemple

 build(:post).atsortingbutes 

Ancienne question, mais fortement référencée … Je pense que la plupart des gens utilisent d’autres méthodes, mais il existe en fait une méthode to_hash , elle doit être configurée correctement. Généralement, le pluck est une meilleure réponse après les rails 4… en répondant à cela principalement parce que je devais chercher un groupe pour trouver ce sujet ou quelque chose d’utile et en supposant que les autres rencontraient le même problème…

Remarque: ne le recommande pas à tout le monde, mais des cas limites!


Du rbuy sur les rails api … http://api.rubyonrails.org/classes/ActiveRecord/Result.html

 This class encapsulates a result returned from calling #exec_query on any database connection adapter. For example: result = ActiveRecord::Base.connection.exec_query('SELECT id, title, body FROM posts') result # => # ... # Get an array of hashes representing the result (column => value): result.to_hash # => [{"id" => 1, "title" => "title_1", "body" => "body_1"}, {"id" => 2, "title" => "title_2", "body" => "body_2"}, ... ] ...