NHibernate like model versioning for rails? - ruby-on-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?

Related

Using the gem paper_trail for tracking the latest news-activity on my website

I'm using the gem paper_trail for keeping track of versions. I wonder, is there any way to create some kind of activity news out of the models it's been included into? For example, I've added it into the models Commentary, User and Article. I want to be to get a list of the latest changes of these models and create something like news of activities:
user A has created a new Category
user B has edited an Article
admin had added a new Article
etc
Is it possible? And how? Seems like yes, but how exactly? Note that, I don't want to retrieve that kind of information from all the models I've included the gem into, but only from the ones I want to.
Since you want it by the user, you should integrate https://github.com/ankit1910/paper_trail-globalid to link the whodunnit part.
PaperTrail::Version.where_object(attr1: val1, attr2: val2)
NOTE: paper_trail gem is for auditing.
Do not forget to check your indexes on your database since relational databases slow as your no. of indexes increase.
Based on my experience with [spree][1] framework and a similar gem, versions table was the largest we had and it grew quiet fast. You may face similar challenges in maintaining this table and adding indexes may cause it to slow down.
My suggestion would be to use a Redis like store to maintain a list of 10 or so recent updates per user which the user may be notified of instead of querying MySQL (essentially caching)

Where to place sql queries in rails?

I have started a rails project on top of a legacy database. Standard practices required to use an ORM, like assigning ID field to each table, haven't been followed. So, I will not be creating all the models matching all the table. I need to run queries joining multiple tables using numerous conditions. I will mostly be using Model.find_by_sql or Model.connection.select_all methods. Where should I put these queries? Should I stash these in one of the models I have created that is involved in the query?
What's the standard practice for such a situation?
As much as possible, you still want to insulate the rest of your application from the details of the database by putting your queries and whatnot into the model layer. So yes, "stashing" in the right model object relevant to what you're trying to do seems like the right thing.
Are you allowed to change the schema of the database? If so, you may want to use migrations to slowly make your database look more like a standard ActiveRecord backing store.
You may also want to look into alternatives to ActiveRecord such as Sequel.
It is good idea to place the sql queries under sql folder under db. You need to create the sql folder.

What's the best database structure for a Rails app like Wufoo?

I am not intending to rebuild Wufoo on Rails but want to create an app along those lines.
Any advice on the best app/database structure for this?
A postgres hstore strategy would be preferable to serializing. And yes, there's a gem for activerecord hstore support.
To quote their readme:
You need dynamic columns in your tables. What do you do?
Create lots of tables to handle it. Nice, now you’ll need more models
and lots of additional sqls. Insertion and selection will be slow as
hell.
Use a noSQL database just for this issue. Good luck.
Create a serialized column. Nice, insertion will be fine, and reading data from
a record too. But, what if you have a condition in your select that
includes serialized data? Yeah, regular expressions.

Keeping track of who did what in 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.

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