Custom Tables in PaperTrail with Rails 4 - ruby-on-rails

I'm pretty new to Rails, and trying to use PaperTrail to handle versioning for all of my models. I'm using PostgreSQL. I want to store the versions table for each model as a separate table, which the PaperTrail README assures me is possible (though it's been marked as an issue several times in the Rails 3 branch).
If I'm subclassing Version like so:
# Allow PaperTrail versions to be in a separate table.
class FooVersion < Version
self.table_name = :foo_versions
# For Postgres, according to PaperTrail README
self.sequence_name = :foo_version_id_sequence
end
Is there a way to get PaperTrail to generate this migration for me? All it seems to want to do is generate a generic migration for a Version table.

No, looking at the code it does not seem like paper_trail will generate it for you.
There are only two migration file templates. One is for the generic versions table, and the other is for adding an object_changes column.
If there are no differences between your custom tables and the generic table other than the name, you can copy the generic migration and replace the table name and index accordingly.

Related

Different table name for Paper Trail?

Is it possible to specify a different table name (other than versions) for the PaperTrail gem?
In my Rails app, I already have a Versions model/table, which has nothing to do with active record versioning (my app let's uses fork a "prototype" and for better or worse I used "version" as a label for these forks). It is quite pervasive through my app, and I don't want to rename this.
When running bundle exec rails generate paper_trail:install, I get Migration already exists: create_versions.
Basically, I would like the table to be PaperTrailVersions along with the methods to access the trail to be similarly namespaced.
Any ideas? Or should I just use the Audited gem which uses a audits table?
PaperTrail supports custom version classes which can have custom table names defined.
class PostVersion < PaperTrail::Version
self.table_name = :post_versions
end
class Post < ActiveRecord::Base
has_paper_trail :class_name => 'PostVersion'
end
As of the failed generate command, I would try these steps (haven't tested them though):
You already have a migration with the name CreateVersions because you already have a versions table. That is why the generate command fails - it cannot create a migration with the same name. I think that you can simply temporarily rename the old migration (for your original versions table migration). You just need to rename the file and the classname inside the file.
Then the generate command should run. It should install a few files, their names will be printed out to the console.
Now open the newly generated create_versions migration file and rename it as well as the class name inside from CreateVersions to a name according to your custom versions table name, such as CreatePostVersions. Also rename any mention of the versions table inside it to your custom table name, e.g. post_versions.
Open all other generated migrations and change the versions table names to your custom table names inside them. There is no need to rename these files though.
Now go back to your original (and now temporarily renamed) create_versions migration file and rename it back to its original name (revert the changes on this file).
Try to run the migrations! It should work now.
The steps may seem cumbersome but they just temporarily rename the old migration to something else so that the generation command can run. Then you just need to change the table name inside the generated migration to the new table name.
The files that will be generated with the generate command can be seen here in the source code. These are the files that you'll need to modify.

Alternative to the globalize gem

I tried out the globalize gem but this seems like a big overhead. Most of the time I just need one attribute translated. I'm using postgreSQL and would rather use a hstore for this. That way I won't get additional tables and performance should be at least as good if not better.
Are there any gems that use this approach or would this mean a custom development?
Seems like you're searching for the hstore_translate gem. I have not tested it but it appears to suit your needs precisely from the description:
Rails I18n library for ActiveRecord model/data translation using PostgreSQL's hstore datatype. It provides an interface inspired by Globalize3 but removes the need to maintain separate translation tables.
I've been using the hstore_translate gem and love it.
Say for example you have a Project model schema with title:string and content:text. If you want content to be translated, all that needs to be done is to create a migration:
class AddTranslationToProjects < ActiveRecord::Migration
def change
add_column :projects, :title_translations, 'hstore'
end
end
and inside of project.rb:
class Project < ActiveRecord::Base
translates :title
end
thats it! Nothing else to do in the form or wherever. Works for integers and booleans as well. The only extra step to do is activate hstore if using postgres: CREATE EXTENSION hstore
I've recently created the gem awesome_hstore_translate, which is based on the original hstore_translate by Rob Worley.
hstore_translate uses alias_method_chain, which got deprecated with Rails 5.0.
My gem has the same functionality as it's original, but it's a bit more modern. It stores it's data in columns without a suffix, because I think the database model looks more clean that way. The raw data is still available. E. g. Page.first.title_raw will give you the hstore hash.

Using a model without migration ? ( just SELECT in database)

I already have a database with the right structure.
I would like to create a rails app just to read into this database, I don't want to insert neither update etc...
Actually, I would like to use rails but handle myself the creation of the database and tables.
Is it possible ?
I've commented every lines into "create" def into the migration file, it works but is there another way ?
Thank you.
rails g model ModelName --skip-migration
You might be able to use this Gem.
gem 'rmre', '~> 0.0.8'
It allows you to create models from an existing schema.
See documentation here: https://github.com/bosko/rmre

Rails with two different Databases

I have used two different databases for my Rails application: MongoDB and MsSQL using Mongoid and activerecord-sqlserver-adapter adapter respectively. Everything is well but there is a problem while generate Model.
The problem is "how can I generate the model that relates to MongoDB or MsSQL differently?"
For example: I want to generate People model relates to MongoID and Animal model with MsSQL. While I generate with command: rails g model Animal name:string it generates the model related to mongoid. How can I generate the model Animal with ActiveRecord that means related to MsSQL.
Please help me.
Thanks
Based on Using Active Record generators after Mongoid installation? I believe this should work:
rails g active_record:model Animal name:string
First let me just check that I've understood your question correctly:
You have 2 databases and a series of models/migrations, and you want a way to tell rails which database to use when running a migration and accessing the database using your model?
If I'm in the right area then you need to add a method to your migration which overrides the default connection() method in ActiveRecord::Migration.
def connection
ActiveRecord::Base.establish_connection(:conn_name).connection
end
Where :conn_name is the name you gave your connection settings in config/database.yml
within your models add the line
establish_connection :conn_name
to the top of your model file and the model will now know which DB to connect to.
So the quick and dirty way that I have handled this in the past (due to my dev team keeping mongoid in the gem file for legacy reasons) is to comment out the out mongoid when you have to do migrations run a bundle, generate and run you migration then uncomment and run bundle again. This is far from best practices but it should work.

Rails/Mongoid database migrations

I am currently working on a rails app where we are using mongoid/mongoDB on the back-end. I understand that I don't need ActiveRecord like migration to migrate the schema, but I do need to migrate data as I change mongoid model definitions. Is anyone else out there running into the same scenario, if so how are you handling it?
Even though you're not making schema changes, you may need to move data between fields, or remove fields that are no longer used in the codebase. It's nice to have migrations that you can run when you deploy new code. I recommend using a gem called mongoid_rails_migrations. This provides you with migration generators like you're used to and provides some organization to migrating data.
class MyMigration < Mongoid::Migration
def self.up
MyModel.all.each do |model|
# label was renamed to name
model.set :name, model[:label] # copy the data from the old field to the new one
model.remove_attribute :label # remove the old field from the document
model.save!
end
end
end
Write a custom rake task to migrate the data as needed
This question addresses the same issue of creating custom migrations in a mongoid setup.
Runtime changing model with mongodb/mongoid
I had the some scenario recently, where I have to do some data migration only once (basically update dirty data);
So what I did have a mongoid migrations in /db/migrate/ and override the db:migrate task so that it creates a collection in mongo db of that app itself, say "migrations", that record the migration that got fired, with that, none of the migration will run again, and you can keep adding migrations with some hierarchy (if in case migration is interdependent).

Resources