Keeping track of who did what in Rails? - ruby-on-rails

What's the best practice way for keeping track of who did what in a mid-sized Rails app? Intercepting all database read/writes and storing that in another table?

you can pretty simply adapt acts_as_versioned to also record information about which user performed the operation. I'd suggest looking into that plugin as versioning is rarely a bad idea.

You can use Observers on callbacks like create/update/delete for several models and save data to another table/model but if you want to have a wiki-like site - acs_as_versioned is better option.

If you'd like to "roll your own" solution you can implement database triggers on insert/update/delete that update a separate table. Otherwise there are several commercially supported data audit applications that can be purchased and configured to track and report on these activites for you at the database level.

Rather than reimplementing, you should try some plugins like acts_as_audited
acts_as_audited is an ActiveRecord extension that logs all changes to your models in an audits table.
or PaperTrail.
PaperTrail lets you track changes to your models' data. It's good for auditing or versioning. You can see how a model looked at any stage in its lifecycle, revert it to any version, and even undelete it after it's been destroyed.
Whichever suits your needs.

Related

NHibernate like model versioning for rails?

In NHibernate it's possible to work with versions using the same table and just add a version number column to that table see here. For severe performance reasons I'd like that logic to be contained in the same table not in a collection table. Is there anything like that for Rails or do I need to roll our own?
I have looked at all the options available like audited, vestal_versions, paper_trail and must say I am disappointed in all of them. They are not only cumbersome to use the right way but also performance bottlenecks. To restore a version in paper_trail I have to do 3 queries to the database to fetch the data to restore and then another query to update.
Do you mean Optimistic Locking?

working with a database record without saving it in rails

I am developing an application using ruby on Rails that is going to be used to train learners in high fidelity simulations in which they need to record notes in an web based electronic record-keeping system.
The idea is to be able to allow users to retrieve a simulated record from the database, interact with it by adding child records that represent procedure notes, messages to other people and the like, and at the end of the session display the changes and additions that were made. After all of that the "template" record will need to be able to be reset to its original state, returning to the state it was in before the user worked with it.
Multiple users will use the same "template" record in different simulation rooms, so changes made by one user should not affect the data available to other users.
I have already developed much of the application using generated scaffolding that I have modified to produce the basic functionality of the record system.
Now I need to figure out the "simulation mode" functionality which allows a user to "tear off" a copy of a record that will be thrown away after changes are made at the end of a session.
Has anyone developed a rails application that has similar requirements to those I listed above?
I am thinking I will need to store copies of the patient and its child objects in session variables. Are there any examples available to that show how to store copies of objects in session variables and modify and add to those objects using forms? Any help and advice would be very appreciated.
I think what you are looking for is version management. There are a number of gems to do this, I suggest looking at:
http://railscasts.com/episodes/255-undo-with-paper-trail
...and see if the kind of functionality can be addressed with paper trail. If not, checkout:
https://www.ruby-toolbox.com/categories/Active_Record_Versioning
https://github.com/collectiveidea/audited
very cool gem, you simply store the audit state in session to which you then roll back.

Preserve external changes in CouchDB with CouchRest Model

I'm using couchrest_model to manage some DBs in Rails. So far, it worked like a charm, but I noticed that if I PUT some data via HTTP request, CouchRest Model doesn't seem to realise that the changes are made, so it wipes off the whole record. Of course, I can see the changes in Futon, but not in Rails. When I enter the console, the previously saved instance is just not there.
Of course, I could use HTTP all the way, but I'd really like to make use of validations and other goodies that are available in ActiveRecord class.
Is there any chance that I can make these two guys work together?
P.S.
If you think/know that this approach will work with any other CouchDB Ruby/Rails gem, please, do tell! =)
I've mentioned CouchRest Model because IMO it's the most up-to-date and advanced gem out there.
I realised that this one was so damn easy, it's just that I was using the wrong tool (apart from being a proper n00b). AFAICT, it's not possible to use CouchRest Model solely to carry out persistent operations on CouchDB backend. All external calls that alter the database record(s) in certain way will somehow "remove" that record from ActiveARecord. Instead, you'd probably like to use CouchPotato, since it supports persistent operations.
I'll be glad to give checkmark if anyone comes up with vaguely better idea that this one.

Generate new models and schema at runtime

Let's say your app enables users to create their own tables in the database to hold their own, custom data. Each table would have it's own schema. What are some good approaches?
My first stab involved dynamically creating migration files and model files bu I'd like to run this on heroku where you can't write to the filesystem.
I'm thinking eval may be the way to go to create and run the migration class and the model class. But I want to make sure the model class exists when a new process of the app is spawned. Can probably do this by storing these class definition with each user as they create new tables and then run through them all at startup. But now it's convulted enough that I may be missing something obvious.
It's probably a better idea not to generate new classes on runtime. Besides all of the security risks, each thread's startup time will be abominable if you ever get a significant number of users.
I would suggest rethinking your app design and aim at generic tables to hold the user's custom data. If you have examples of data structures that users can create we might be able to help.
Have you thought about a non-sql database for those tables? Look at CouchDB - there are several plugins on Github that integrate it with rails. Records in the database are JSON documents, with arbitrary key-value structure. May be perfect for a user-defined schema.
There is (was?) a cool Wiki project, called Informl. It was a Wiki, not just for web pages but for web applications. (Get it? It's informal because it's a Wiki, it's got forms because it is an application, and it's user-generated, thus Web 2.0, which means that according to an official UN resolution it is legally required to have a name which is missing a vwl.)
So, in other words, it was not just about user-generated content, but also user-generated structured data.
They did this by generating PostgreSQL-specific SQL at runtime to create new tables and then have ActiveRecord reload the schemas.
The code is up on RubyForge. It's based on Rails 1.2.3. I guess you could do much better than that today, especially with the upcoming extensibility interfaces in Rails 3.

What's the best way to store the ActiveRecord Models with Versions and their Associations with Versions?

If all I have is one model (for example Wiki) and want to save it along with its versions, I could use acts_as_versioned plugin which stores the wikis in "wikis" table and its versions in "wikis_versions" table. This is plain an simple even if I want to moderate the latest version before showing it to the public using a field as status with "pending review/ published".
What's the best way to handle Wiki with associations (for example attachments, assets,..) which also have versions? And how would you moderate it? Do you create a new version to wiki even though only its association is changed just to keep the flow going, if so what about other associations?
What's the best way to handle it with little db overhead?
Thanks in advance.
I have used both acts_as_versioned and acts_as_audited.
I prefer the latter because it uses a single table. Using acts_as_versioned we've had issues with changes to versioned tables requiring extra migrations => this adds extra complexity to our build and deployment process.
Richard Livsey has a nice plugin for this that works with acts_as_versioned.
http://github.com/rlivsey/acts_as_versioned_association/tree/master

Resources