2

I have a Rails application and a JSON file which contains the data, instead of creating table for a model i want to point my model to read that jSON file, and i should be table to treat that file like a table, please suggest.

Sachin Singh
  • 7,107
  • 6
  • 40
  • 80
  • why don't you try to create a table with your json file? – power Jul 15 '16 at 10:01
  • You cannot use ActiveRecord to read directly from your JSON file. You will need to rewrite all needed methods to work directly on your JSON. I would suggest to write a importer. – spickermann Jul 15 '16 at 10:24
  • @spickermann thanks please post an answer. – Sachin Singh Jul 15 '16 at 10:44
  • 1
    Sample code for an importer cannot be provided, because that depends on the structure of the JSON and the attributes in the table - both is unknown... – spickermann Jul 15 '16 at 11:01
  • Confirming you want a 100% JSON datastore? And that it's read-only? It's very do-able. Want to confirm before I post answer. – Elvn Jul 15 '16 at 14:06
  • Please read "[ask]". It's difficult to tell exactly what you're trying to do. Example code along with an explanation of why it doesn't do what you want would help also. In general it's not a good idea to treat a JSON file for storage of data as it's slow. If you want a JSON version of data, then write that explicitly. If you want to read JSON data and import it, then do that as a separate task. – the Tin Man Jul 15 '16 at 19:42
  • 1
    I think your question is perfectly clear. For JSON datastore access you would use ActiveModel -- start here http://api.rubyonrails.org/classes/ActiveModel/Model.html – Elvn Jul 16 '16 at 13:46

3 Answers3

2

If I understand you correctly, you want a model that uses a JSON file as it's "backend DB" instead of a normal DB?

In order to get a Rails model to point to a JSON file, you would need to use a JSON DB adapter, and I'm not sure if there is one for Rails.

Rails uses what are called "adapters", where the same code:

Model.find(1)

Will work on any DB (PostgreSQL, MySQL, SQLite3, etc...) because the Model.find() method has been implemented by each adapter.

This allows the interface for the developer to remain the same as long as the adapter implements it.

It avoids the problem where every DB creator implements a different interface, and now everyone has to learn those particular methods (convention for the win!).

All that said, I can't find a JSON DB adapter, so if you want that functionality you'll have to read a JSON file and search against it.

However, if you're talking about using client-side storage with a JSON file, this isn't possible because client-side only understand JavaScript and a Ruby model (class) is on the backend server. They don't directly talk to each other. In that case, you'll have to implement a JavaScript model that maps to the JSON data.

Dan L
  • 4,319
  • 5
  • 41
  • 74
2

MySQL as in-memory-database

Rails with in memory database has a way to use MySQL in-memory; then you load your data from the JSON file at the start and dump it out at the end (or after commits).

In-memory DB adapter

https://github.com/maccman/supermodel exists but looks dead (4 years old). Maybe you find others?

Rolling it yourself with Nulldb

Use https://github.com/nulldb/nulldb to throw away all SQL statements and register some hooks (after_save etc.) to store them in some hash. You then load that has into memory at the start and dump it out to JSON later.

Separating concerns

My favourite approach, maybe too late if you have lots of working code already:

  • Separate your active-record code from your actual domain model. That means, if you today have a model class Stuff < ActiveRecord::Base, then separate that into class StuffAR < ActiveRecord::Base and class Stuff.
  • Stuff then contains an instance of StuffAR.
  • Using the proper ruby mechanisms (i.e., BasicObject::method_missing), you can delegate all calls from Stuff to StuffAR by default.
  • You now have complete control over your data and can do whatever with it.

(This is only one way to do it, depending on how dynamic/flexible you want to be, and if you need a real DB part-time, you can do it different; i.e. class Stuff < StuffAR at the one extreme, or not using a generic method_missing but explicitly coded methods which call StuffAR etc. - Stuff is PORO (plain old ruby objects) now and you use StuffAR just for the DB contact)

In this approach, be careful not to use Stuff like an AR object. I.e., do not use Stuff.where(name: 'xyz') from outside, but create domain methods for that (e.g., in this example, Stuff.find_by_name(...).

Yes, this is coding overhead, but it does wonders to improve your code when your models become big and unwieldy after a time.

Don't need AR at all?

If you do only want to use JSON ever, and never use a real DB, then do the same as before, just leave StuffAR out. It's just PORO then.

Community
  • 1
  • 1
AnoE
  • 8,048
  • 1
  • 21
  • 36
1

I think you have to import your JSON file to the database (e.g. sqlite3) to handle it as a table.

The other workaround would be:

Create a JSON importer for your model which fills the Users from the JSON into an Array of users. If you do that, you'll have to write the whole searching/ordering by yourself in plain ruby.

I don't know what your current circumstances are, but if you would like to change some data or add data, I suggest using a simple and lightweight database like sqlite3

siegy22
  • 4,295
  • 3
  • 25
  • 43