Home > front end >  How to save data into JSON with Ruby and use it later?
How to save data into JSON with Ruby and use it later?

Time:12-23

I'm building a simple "School Library" app to be run in the terminal, and I build most of my files as classes. Now I want to store the data I receive like book title, author, teacher names and more and I want to store it in a JSON file. The problem comes when I want to write the file using Ruby, I do File.write("path_to_my_file", data) and it is writing into the JSON file but it's not writing what I want. Instead of writing

[
  "Title": "My title",
  "Author": "My author"
]

or something similar, I'm getting

["#<ActualBook:0x00000237dbce9ec8>, #<ActualBook:0x00000237dbdg3r8>"]

where "ActualBook" is the name of my class to create a new book. I don't know how to achieve this. I tried this code but with no luck:


class Storing
  def initialize(arr)
    @books = arr
  end

  def stores_data
    data = []
    @books.each do |book|
      data.push([book.title, book.author])
    end
    send = JSON.dump(data)
    if !File.exist?("./data/books.json")
      File.new("./data/books.json", "w ")
    end
    File.write("./data/books.json", data)
  end
end

Any idea?

CodePudding user response:

You Need to Serialize to JSON First

You are currently writing native Ruby objects to your file, not JSON. To serialize an object to JSON, you need to call a method like #to_json on it after requiring the JSON module.

For example, using Ruby 3.0.3:

require 'json'

books = [{"Title"=>"My title", "Author"=>"My author"}]
File.open("books.json", "w") { |f| f.puts books.to_json }

will write the expected JSON object of [{"Title":"My title","Author":"My author"}] to your file and then close itself.

If you want, you can validate that this worked in Ruby, or at the command line with jq. As a command-line example:

jq . books.json 
[
  {
    "Title": "My title",
    "Author": "My author"
  }
]

There are certainly other ways to generate JSON objects in various formats for serialization, but that's the missing piece in your code. You have to convert your Ruby objects to JSON objects before writing them out to the file, or (in your case) you just end up writing the implicit #to_str value of the object instead.

  • Related