Rails Model Data Over Time - ruby-on-rails

I have a model that has data that can change monthly. I'd like to track that data over time so that we can pull up to the last 24 months worth (creating line graphs and such).
What's the best way to store that kind of data in a Rails model?

Create a model that belongs_to the first table which stores the data and the time for that data.
When the value on the first model changes, you make a new row in the values table with the corresponding value and time.

Related

When last a table column was modified

Is there a way to know when a user updates a table column? For example, at what time a user changes their last name?
Im not interested when last a table was updated; only the column. Is it possible using Rails 5 and PostgreSQL?
If you are including timestamps in your models (.created_at and .updated_at) then .updated_at will tell you the last time that the record (i.e. the database row) was updated.
But that will not tell you which attribute of the record was changed (i.e. which database column). Nor will it tell you which user changed it, or if it was changed automatically by something in your system, etc.
You would need the schema to do that. You can a new table called as user_logs and implement a trigger which stores old_record and new_record. This will help you to get the desired log for change.

How to save historical data in Rails?

What is the best way to save historical data?
One way would be just using what I already have - rails g scaffold value_history_datapoints item:references value:float - then just iterate through items and create ValueHistoryDatapoint for each of the item.
BUT
The database is already clunky, has lots of datapoints, all of which must be kept, but there are some data that are already obsolete and useless (old items that will never be used again, if nothing goes south).
Would it be better to somehow store all the data as json in the item's model? Or is it just better to stick to relations?
Have you checked the paper_trail gem? It creates a versions table that can store object data and changes for each CRUD operation.

Core Data: Fetch and group different entities based on date created

Case:
I am working on an app using Core Data with 2 different entities Note and Sleep. During a day there may be added instances of these entities multiple times.
Note stores timestamp (Date), a note (String) and a few other irrelevant attributes. Used to take daily notes.
Sleep stores timeStart (Date) and timeEnd (Date) - Used to track the user's sleep.
Issue
I want to fetch all the entries of both Entities Note + Sleep and group them by timestampand timeEnd; so it can be displayed in a table view with a cell/row for each date.
The sleep data will be used to calculate the total hours of sleep (e.g. if the user sleeps twice a day)
Some days there might be only Notes and other days only Sleep.
How would I go about this? I hope it makes sense; otherwise please let me know.
A Core Data fetch request can only fetch objects of one particular entity (and optionally
the sub-entities). The same is true for a fetched results controller.
Therefore to display
Note and Sleep entities together in a table view, you have the following options:
use a single entity that holds all attributes, or
make Note and Sleep inherit from a common parent entity, or
create a third entity Entry with the timestamp attribute and to-one relationships to Note and Sleep.
Note that in the second case Core Data would also store all objects in a single
table containing all attributes.
In either case, you can sort the objects on the timestamp, or group them
into sections using the sectionNameKeyPath parameter of the fetched results
controller.
The only alternative would be to fetch the objects separately and merge them, but then
you lose all advantages of the fetched results controller, like automatic
change tracking.

rails sums model

I have a lot of sum functions in my app. I am moving all data sums to a separate model...lets call it...sums. This will make calling those numbers faster as I wont nail the database everytime I need to sum many rows.
What I would like to do is update the sum row (many attributes) each time certain other models are created or updated. I am trying to this via each model using a class method but for some reason its not working.
Im wondering where I can create a universal method that can be called from an after_create callback for whichever models I choose. The sum is associated to an account, which is not the model being updated. Other account associated models are the ones that will hit the sums model. Therefor, I will probably need to pass self.account_id to the callback method.
Like Papertrails versions model, that is updated everytime another model is saved.
Have a look at Statistics gem.
It has a cache option that uses Rails cache to prevent repeated aggregation calls to database.
I would prefer something like this as opposed to have an update every time a property gets updated. If you are not planning to hold the sums model in memory, then you will have to fire as many updates to sums table as there are actual updates.
While it may be OK to have write-time overheads, as opposed to read-time, Statistics comes with other options to optimize.

Saving daily data for a model in Rails

I have an article model and a user model. The user can follow that article, but can't unfollow it. I'd like to keep track of new followers for an article, and to retrieve it for when I want to plot it. (Assume, for now, that plotting is not the problem.)
I'd like every article to have a list of the every date since that article was created. So it will have:
article.newfollowers[1/1/2012] = 35
article.newfollowers[2/1/2012] = 4
Every time a user follows an article I would do
This.newfollowers[Date()]++
Obviously saving such data means that each row in the article database has hundred of attributes (for each date).
How would I save the data within the article model? How do I declare/define such attribute?
If you don't need to query for the dates directly, take a look at ActiveRecord::Store. You'll need to be using Rails 3.2.0 at least, but would prevent you from having to add so many columns.
Another solution might be to use a Redis sorted set, using the date timestamp as the score, and the new followers as the value.

Resources