I have been using papertrail on a project for about a year with no issues. Right now I'm using it on the latest available version (10.3.1), with ruby 2.4.9 and rails 5.1.7. But recently when I ran rake db:migrate the versions table was altered automatically on my schema, removing the rails default id as primary key and adding a bigint field also called id:
create_table "versions", id: false, force: :cascade do |t|
t.bigint "id", null: false
t.string "item_type", null: false
t.integer "item_id", null: false
t.string "event", null: false
t.string "whodunnit"
t.text "object"
t.datetime "created_at"
t.text "object_changes"
t.index ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id"
end
This change made rails start complaining about ActiveRecord::IrreversibleOrderError, as no primary key was defined for the versions table. Now I'm wondering, what happened? Does this have something to do with rails 5.1 changing ids to bigint? It makes no sense to me as i've been on the same rails versions (5.1.7) since the start, and this change was made about 4 years ago.
Thanks.
Ok, so I'm still a bit confused, mostly as to why the schema was changed and versions had no primary key. But I think the issue with ActiveRecord::IrreversibleOrderError was caused by a bump on rails_admin (upgraded from 1.4.3 to 2.0.2). For some reason rails_admin now displays the versions table by default on the left menu, inside a PaperTrail group. That combined with the fact that ActiveRecord wasn't being able to order the versions table (as there was no primary key or ordering configured), made ActiveRecord start to raise the IrreversibleOrderError exception.
To fix this I added the following line to rails_admin initializer (config/initializers/rails_admin.rb):
RailsAdmin.config do |config|
...
config.excluded_models = [PaperTrail::Version]
...
end
I also executed a SQL instruction to add id as primary key on versions again (allowing to keep the versions section on rails_admin, even though I removed it):
ALTER TABLE versions ADD PRIMARY KEY (id);
You could add this to a migration (execute("SQL GOES HERE")), but it's kind of weird, cause if you reset your DB and run the migrations from scracth it will complain of the primary key being defined twice on the same table (at least, that was what happened in my experience).
I still don't think this is the final solution, as I don't understand the source of the error, so I won't accept it as the solution for now. If anyone can shed any light, will be greatly appreciated!
Related
On my migration file I have a number of new fields creation.
create_table :mytable do |t|
t.string :my_field, null: false
.........
And I am getting the following
Metrics/AbcSize: Assignment Branch Condition size for change is too high. [<1, 17, 0> 17.03/17]
What is the proper way to avoid that?
It's a common practice to exclude the db folder in your .rubocop.yml.
AllCops:
Exclude:
- 'db/**/*'
Most of the time we Ignore ./db folder in rubocp.yml file. Other than that we can disable cops for a specific block of code. Here is the answer Rubocop, how to Disable/Enable cops on blocks of code
I'm trying to install activeadmin on rails with devise.
I added gemfile and ran
rake db:migrate
and i met these errors.
== 20170821153121 DeviseCreateAdminUsers: migrating ===========================
-- create_table(:admin_users)
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:
SQLite3::SQLException: table "admin_users" already exists: CREATE TABLE "admin_users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar DEFAULT '' NOT NULL, "encrypted_password" varchar DEFAULT '' NOT NULL, "reset_password_token" varchar, "reset_password_sent_at" datetime, "remember_created_at" datetime, "sign_in_count" integer DEFAULT 0 NOT NULL, "current_sign_in_at" datetime, "last_sign_in_at" datetime, "current_sign_in_ip" varchar, "last_sign_in_ip" varchar, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL)
/Users/admin/.rvm/gems/ruby-2.4.1/gems/sqlite3-1.3.13/lib/sqlite3/database.rb:91:in `initialize'
/Users/admin/.rvm/gems/ruby-2.4.1/gems/sqlite3-1.3.13/lib/sqlite3/database.rb:91:in `new'
/Users/admin/.rvm/gems/ruby-2.4.1/gems/sqlite3-1.3.13/lib/sqlite3/database.rb:91:in `prepare'
/Users/admin/.rvm/gems/ruby-2.4.1/gems/sqlite3-1.3.13/lib/sqlite3/database.rb:137:in `execute'
...
Well the error is fairly self explanatory, your database already has a table with the same name Devise/Active Admin wants to use and table names must be unique.
Did you already at some point already use/try the activeadmin gem? If you already created the tables for it, trying to create and execute new migrations will fail, but you should be able to either just use those, or delete them and make fresh ones.
Or does your application just happen to have a AdminUser model for its own use? If it does one of them has to change.
You should be able to see either case in your db/schema.rb, or in the old migrations in db/migrations/. If you tried deleting/reverting a migration by just deleting its migration without script without rolling back first (either rails db:rollback or a DB backup), you may also have old tables actually in the DB, which you may want to manually delete.
If you do need to rename the Active Admin tables, the advice given in Github Database tables name prefix #4960 is to manually edit the migration and use self.table_name= in the models to tell them the new names.
Well, the error it self repeat that you have already the same table called "admin_users".
Please run the command on rails console to see your already created tables like this way:
ActiveRecord::Base.connection.tables
If you would find same table in the list then you need to delete that table manually or another way is just drop your db and recreate it after that you can able to run your new migration.
I recently looked at my schema.rb file and was alarmed to find that certain columns that do exist in my database do not appear, and some tables are missing entirely. The missing columns were added to the database through "def change add_column" migrations, though some columns that were added in that way do appear as expected in schema.rb.
On closer inspection, I realized that schema.rb has not been updated since I created the Users table.
20151019205241_create_users.rb:
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :name
t.string :email
t.timestamps null: false
end
end
end
This has not caused an issue for me in practice, but I thought schema.rb was supposed to be kept automatically updated, and that it would be important to have it updated in order to recreate the database. Can anyone help me figure out why it would not be updating?
One possibility is that it stopped being updated when I switched my database from sqlite3 to postgresql. I don't remember exactly, but I think the timing makes sense.
You can use rake db:schema:dump to re-create the file from the current database structure.
Schema file is independent from the driver so migrating from sqlite3 to PostgreSQL shouldn't matter. Make sure that version for definition in the file is not greater than current the current date. You can also add the whole file to the question's snippet.
Let's say I have a migration that creates a table 'pages' , this is my migration:
class CreatePages < ActiveRecord::Migration
def up
create_table :pages do |t|
t.string "name" , :limit => 50
t.integer "permalink"
t.integer "position"
t.timestamps
end
end
def down
drop_table :pages
end
end
and that I've created the appropriate migration file X_create_pages.rb and ran it(the table is created in the database).
Now after a few days I realize the structure isn't complete and I need to add another column to my pages table .
What is the best practice , do I create a new migration file with add_column method or do I just change the current migration file's up method -e.g just add my columns to the up method (and then move down a version and then up again - so to run the up method?)
The practice should be you create a new migration to add the new column. This becomes the simplest and risk free path. Of course, we can talk about unseen circumstances!
Updating original migration files should not be used after application is released to production; at least this is what the practice should be. But, this also depends on applications, if you don't have a table that is referenced elsewhere then backing up the data, adding the column and restoring the data is also a possibility which is enabled by this approach of directly modifying the original migration file and rolling down that version and migrating up that version again.
While you are on development, the choice I guess is yours. You could choose either!
Once a migration has been checked into source control it shouldn't be changed.
Modifying a migration on your development environment providing it hasn't been checked into source control is perfectly fine.
Once a migration has been checked in it may have been run by your team mates on their development environment or even been deployed and run in production.
Changing previously committed migrations is going to make you very unpopular in your team very quickly as team mates struggle to understand why their database schema is different from yours but all the migrations have been run.
Now in rails we can use
t.string instead of t.column
using t.string is easy.But
t.column is a deprecated feature?
any other advantage of using t.datatype other than easiness.
Is there any way to convert all current migrations to new style easily.
t.column is not deprecated. You can use it without losing any sleep. The t.string syntax is just a "sugar" on top of the good old t.column.
1) sed. :)
2) Do you need to convert them? If you have schema.rb checked in as advised (or even a local copy somewhere), that should represent the current state of the database, right? If you do a "rake db:schema:dump" that should set you up with all the migrations up to that point in one schema.rb file, then you can go from there.