ruby-on-railsrubyobjectstoring-data

How do I store a Ruby object in my Rails app without using a database?


Given


Objective

Save this quiz object to be accessed later by all users of the app.


Question

How to store and access this quiz object in Rails 6.0 without representing it in a database?


Possible Solutions


What I've checked out so far

SO - Store json object in ruby on rails app: Because this is JSON, going back and forth between the JSON format and the parsed format is more intuitive.

SO - Can I create a database of ruby classes?: I don't really get the answer to this question. Some of the links are broken. I think the question is pretty similar, though.


Solution

  • Is it possible to use Marshal to pickle the object and save it to be used later?

    Yes, using your same code as example, you could serialize and deserialize the object recovering it just as it was.

    irb(main):021:0> marshalled = Marshal.dump(ch1_history_quiz)
    => "\x04\bo:\tQuiz\n:\v@topicI\"\x0EChapter 1\x06:\x06ET:\f@courseI\"\fHistory\x06;\aT:\x13@highest_gradeii:\x13@failing_gradeiF:\x1A@answers_by_questions{\x06I\"6Which ancient civilisation created the boomerang?\x06;\aTI\"\eAboriginal Australians\x06;\aT"
    irb(main):022:0> deserialized = Marshal.load(marshalled)
    => #<Quiz:0x00007f81d3995348 @topic="Chapter 1", @course="History", @highest_grade=100, @failing_grade=65, @answers_by_questions={"Which ancient civilisation created the boomerang?"=>"Aboriginal Australians"}>
    

    Another option, more readable is serializing your object in YAML format:

    irb(main):030:0> yamled = YAML.dump(ch1_history_quiz)
    => "--- !ruby/object:Quiz\ntopic: Chapter 1\ncourse: History\nhighest_grade: 100\nfailing_grade: 65\nanswers_by_questions:\n  Which ancient civilisation created the boomerang?: Aboriginal Australians\n"
    irb(main):031:0> deserialized = YAML.load(yamled)
    => #<Quiz:0x00007f81d398cb80 @topic="Chapter 1", @course="History", @highest_grade=100, @failing_grade=65, @answers_by_questions={"Which ancient civilisation created the boomerang?"=>"Aboriginal Australians"}>
    

    With any of both options, you could save it later in a DB text field (with enough space to keep big objects), a plain-text file or whatever you choose.
    Also, something very important to keep in mind are the security issues about using marshal or yaml, so objects must always be loaded from trusted sources.