1

I have a JSON-file with some Data and I like to create a Model that represents the Data from the JSON-file like a ActiveRecord class.

My JSON looks like the folling (Not the real data just a example):

[
 {
  "name": "Test",
  "model": "L33D",
  "value": 69
 },
{
  "name": "Test2",
  "model": "Chill",
  "value": 420
 },
 {
  "name": "Test3",
  "model": "Banana",
  "value": 1337
 }

]

So it would be nice to have a model where I can write stuff like MyModel.find by :name "test3"

How do I write a Model for none databases related Data? Or do I just do plain old ruby and write a normal Class?

Zero Soul Eater
  • 132
  • 1
  • 13

2 Answers2

4

Is it possible - yes.

In Rails you have ActiveModel::Model which is a module that includes validations, attribute assignment, form integration, polymorphic routing etc. Pretty much everything except the actual persistence layer which is usually provided by ActiveRecord. You can also pick and choose features by just including the submodules.

Starting with Rails 5 you also have ActiveModel::Attributes which provides a public api to features that used to be internal. It provides type casting and a good way to define default values.

class MyModel
  include ActiveModel::Model
  include ActiveModel::Attributes # not included in the above
  attribute :awesomeness, :integer, default: 0
  # ...
end

But how do I use it with a JSON file?

You can create a class method or a separate respiratory class that loads and parses the JSON file and creates model instances:

class MyModel
  include ActiveModel::Model
  include ActiveModel::Attributes # not included in the above
  attribute :awesomeness, :integer, default: 0
  # ...

  def self.all
    data = JSON.parse(File.open('/path/to/file.json'))
    data.map do |hash|
      new(hash)
    end
  end
end

Is it a good idea?

Not really unless your use case is very simplistic. To find a single entry you have to parse and load the entire file into memory. And then you have to use the basic array manipulation from enumerable. Any sort of database system is optimized for doing this far more effectively.

If you are deploying to any kind of ephemeral file system like Heroku it has the same cons as SQLite. Any changes to the file will be completely overwritten regularly.

If you are deploying via git it also means that you have to check your data into your codebase. This is rarely a good idea as it greatly increases the churn and the amount of noise you have to sift through to find actual changes in the codebase.

Any nosql or sql database can really do this better.

max
  • 96,212
  • 14
  • 104
  • 165
  • Realy cool answer! thank you! I know my case is very specific, I don't have a huge file by now and the goal was to reuse this file in other Projects and to develop this fast :) – Zero Soul Eater Nov 21 '19 at 18:08
0

You would write plain old Ruby and provide the functionality you need. ActiveModel isn't really useful here.

If you were reading from a RESTful API that outputted JSON, you could use ActiveReource, but that won't really help if you're just loading a file off disk.

user229044
  • 232,980
  • 40
  • 330
  • 338
  • its just a file off the disk. – Zero Soul Eater Nov 07 '19 at 13:30
  • But it would be realy cool if could make a model out of this, so my GraphQL could handle this out of the box – Zero Soul Eater Nov 07 '19 at 13:30
  • 2
    @ZeroSoulEater You could include modules like `ActiveModel::Model` to provides some base behaviour. *"It includes model name introspections, conversions, translations and validations. Besides that, it allows you to initialize the object with a hash of attributes, pretty much like Active Record does."* - [ActiveModel::Model](https://api.rubyonrails.org/classes/ActiveModel/Model.html) – 3limin4t0r Nov 07 '19 at 14:34
  • @3limin4t0r cool that looks like it could work! Thanks, I will try it. – Zero Soul Eater Nov 07 '19 at 15:38