ActiveRecord::Migration unitialized constant error. - ruby-on-rails

Disclaimer: I don't know ruby.
I've been trying to setup this ruby application. I'm trying to debug why I get an uninitialized constant error:
rake aborted!
StandardError: An error has occurred, all later migrations canceled:
uninitialized constant CreateSyncsTable::Syncs/var/rails/cycs/cycs/db/migrate/20100818122117_create_syncs_table.rb:8:in `up'
Below is the file contents of 20100818122117_create_syncs_table.rb.
class CreateSyncsTable < ActiveRecord::Migration
def self.up
create_table :syncs do |t|
t.timestamps
t.integer :remedy_query_low
t.integer :remedy_query_high
end
Sync.create :remedy_query_low => 0, :remedy_query_high => 0
end
def self.down
drop_table :syncs
end
end
To my understanding, line 8 is trying to create a new entry into the syncs table. I don't know exactly why the syntax for doing so is as follows:
Sync.create :remedy_query_low => 0, :remedy_query_high => 0
Nor do I understand why or where "Sync" comes from. Moreover, I don't know what constant is uninitialized.
Any help to debug this is appreciated. For the record, I am using centOS 7, Maria DB and ActiveRecord version 3.2.18.
I reviewed the API to see if that would help. Since I don't know ruby, I don't find it of much help.

Try adding in a call to ActiveRecord::ModelSchema.reset_column_information as it "resets all the cached information about columns, which will cause them to be reloaded on the next request", allowing you to create Sync entries immediately after creating the table in the migration:
class CreateSyncsTable < ActiveRecord::Migration
def self.up
create_table :syncs do |t|
t.timestamps
t.integer :remedy_query_low
t.integer :remedy_query_high
end
Sync.reset_column_information
Sync.create :remedy_query_low => 0, :remedy_query_high => 0
end
def self.down
drop_table :syncs
end
end
Personally, I would recommend removing the Sync.create :remedy_query_low => 0, :remedy_query_high => 0 statement altogether since I think Rails migrations are best used for schema migrations only, and data migrations are best put in rake tasks (a great reason why can be found here).

In this case, Sync is referring to a model. You should have a file in app/models/ called sync.rb, which is the model definition for the Sync class. This is a Rails convention for defining models.
You can use models in your migrations (you've been looking at a migration). However, it's generally not recommended to use your app's models in the migration, because you can end up with conflicts.
What's recommended is to define a proxy model in your migration, which takes the place of the app model for the purposes of the migration. You declare the proxy model at the top of your migration file, so that it's local to the migration.
Try this code:
class Sync < ActiveRecord::Base
end
class CreateSyncsTable < ActiveRecord::Migration
def self.up
create_table :syncs do |t|
t.timestamps
t.integer :remedy_query_low
t.integer :remedy_query_high
end
# Reset ActiveRecord cache of Sync details
Sync.reset_column_information
Sync.create :remedy_query_low => 0, :remedy_query_high => 0
end
def self.down
drop_table :syncs
end
end
The additional call to Sync.reset_column_information tells Rails to reset the cache of information about the model because the table structure has changed. This will prevent issues, such as trying to access the new columns added in the migration.

Related

How to Delete Table from Database permanently in ROR

I've generated a scaffold and then migrated my database. After that, I destroyed my scaffolding and then generated scaffold again and try to migrate my database but I got an error that this table already exists. How can I delete that table from the database?
One other easy way to do so :
open rails console and use this command :
ActiveRecord::Migration.drop_table(:your_table_name)
If you haven't pushed your code then the solution given by #Cryptex Technologies works fine. But if you have(i.e if you are using version control) then i won't recommend that approach. In that case you should create a new migration something like this:
class RemoveTable < ActiveRecord::Migration[5.2]
def up
drop_table :table_name
end
def down
create_table :table_name do |t|
t.string :field_name_1
t.text :field_name_2
t.timestamps
end
add_index :table_name, :field_name_1, unique: true
end
end
To delete that table, you need to run the command
rake db:rollback
and if you want to delete the database of your current application.
then you need to run the command
rake db:drop.
Rails automatically generates migration, thanks to the command line generator.
For instance, if you want to remove the Users Table write a command line statement like this:
rails generate migration DropUsersTable
This will generate the empty .rb file in /db/migrate/ that still needs to be filled to drop the “Users” table in this case.
A Quick-and-Dirty™ implementation would look like this:
class DropUsersTable < ActiveRecord::Migration
def up
drop_table :users
end
def down
raise ActiveRecord::IrreversibleMigration
end
end
It’s “correct” as it shows that the migration is one-way only and should not/can not be reversed. But in order to make a truly clean job in case these modifications were to be reversed we need to have a symmetrical migration (assuming we could recover the lost data), which we can do by declaring all the fields of our table in the migration file:
class Dropusers < ActiveRecord::Migration
def change
drop_table :users do |t|
t.string :name, null: false
t.timestamps null: false
end
end
end
This can be long if the model is complex, but it ensures full reversibility.
Here again, changes will enter effect as usual after running rake db:migrate.

ruby on rails: ratyrate on rails 5? migration error aborted

I'm trying to get back into RoR after a long hiatus, and was getting an error when I tried to rails db:migrate:
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:
Directly inheriting from ActiveRecord::Migration is not supported. Please specify the Rails release the migration was written for:
the errors continue...
I'm thinking its because of the gem ratyrate.
In one of the migration files:
class CreateRatingCaches < ActiveRecord::Migration
def self.up
create_table :rating_caches do |t|
t.belongs_to :cacheable, :polymorphic => true
t.float :avg, :null => false
t.integer :qty, :null => false
t.string :dimension
t.timestamps
end
add_index :rating_caches, [:cacheable_id, :cacheable_type]
end
def self.down
drop_table :rating_caches
end
end
is it because rails 5 don't use def self.up / def self.down? and instead should be using def change?
If that's the case, is it okay for me to just change the def setf.up to def change and then remove the def self.down block?
In addition to this, why is there even a def self.down calling to drop the table when its creating the table? Does it not get executed, only when you db:rollback the database?
Thanks
Since you are inheriting from ActiveRecord::Migration the migration is cancelled.
You should therefore inherit from ActiveRecord::Migration[5.1] and the migration should work. Change the first line to:
class CreateRatingCaches < ActiveRecord::Migration[5.1]
(5.1 specifies the rails version, adapt acordingly, e.g. ActiveRecord::Migration[4.2] etc.)
See this answer for more information about change vs. up/down in migrations or read this part in the official guide for detail information about the different aspects about them.

Why are the methods up and down not being created with my subclass of ActiveRecord::Migration?

I'm reading Rails 3 in Action and following the commands verbatim. However, when I run the commands
rails new things_i_bought
cd things_i_bought
bundle install
rails generate scaffold purchase name:string cost:float
The book says I should get this code:
class CreatePurchases < ActiveRecord::Migration
def self.up #not created in my code
create_table :purchases do |t|
t.string :name
t.float :cost
t.timestamps
end
end
def self.down # not created in my code
drop_table :purchases
end
end
I get this code instead:
class CreatePurchases < ActiveRecord::Migration
def change
create_table :purchases do |t|
t.string :name
t.float :cost
t.timestamps
end
end
end
Why are the class methods up and down not being created for me? I'm using
rails 3.1.1 and ruby 1.9.2.
thanks for reading my book!
As JacobM and dbalatero have already explained, this is a new feature in Rails 3.1. This particular feature was added by Aaron Patterson as a way to simplify the migration syntax. In earlier versions of Rails, you would have to do as the book shows:
class CreatePurchases < ActiveRecord::Migration
def self.up
create_table :purchases do |t|
t.string :name
t.float :cost
t.timestamps
end
end
def self.down
drop_table :purchases
end
end
But that's kind of repeating yourself. Aaron created a migration syntax that looks good and is simpler, calling only the methods necessary for migrating forward, but also allowing the migrations backwards (known as a "rollback") too. The same migration written with the Rails 3.1 syntax is this:
class CreatePurchases < ActiveRecord::Migration
def change
create_table :purchases do |t|
t.string :name
t.float :cost
t.timestamps
end
end
end
So when this migration runs "forwards", Rails will create the purchases table with the fields. When you roll it back (or run it "backwards") then Rails will know to drop the table.
This syntax isn't entirely perfect however, and you'll run into problems with methods such as change_column. When that happens, it's best to stick with defining both the def up and def down methods in the migrations:
class CreatePurchases < ActiveRecord::Migration
def up
change_column :purchases, :cost, :integer
end
def down
change_column :purchases, :cost, :float
end
end
That's because in this example Rails won't know how to switch it back to the previous type. I hope this explains it better!
This is a new feature in Rails 3.1. For changes that Rails can figure out how to reverse, such as creating a table, you simply create a "change" method with the code that would have gone in "up", and it figures out how to do "down" on it's own.
You can also define "up" and "down" methods yourself -- for some changes (such as dropping a column) Rails won't be able to figure it out -- but the syntax is a bit different; it's not just def up instead of def self.up (they're now instance methods instead of class methods).
I believe in the new Rails 3.1, the database migration methods are self-aware about how to run an up/down migration.
Therefore, if you define a def change method, it will try to use those self-aware methods: in this case, create_table knows to do DROP TABLE in a down context, and CREATE TABLE in an up context.
If you want the old style, you can probably keep using it and define your own self.down and self.up methods as the book describes.
Edit: here's a link to the blog post on this, called "Reversible Migrations": http://www.edgerails.info/articles/what-s-new-in-edge-rails/2011/05/06/reversible-migrations/index.html

Rake aborted... table 'users' already exists

I have created a database with devise and the nifty generator. I'm trying to make a new database with the nifty generator (rails g nifty:scaffold Asset user_id:integer), but when I try to migrate the database (rake db:migrate), I get the following error:
charlotte-dator:showwwdown holgersindbaek$ rake db:migrate
== DeviseCreateUsers: migrating ==============================================
-- create_table(:users)
rake aborted!
An error has occurred, all later migrations canceled:
Mysql2::Error: Table 'users' already exists: CREATE TABLE `users` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `email` varchar(255) DEFAULT '' NOT NULL, `encrypted_password` varchar(128) DEFAULT '' NOT NULL, `reset_password_token` varchar(255), `reset_password_sent_at` datetime, `remember_created_at` datetime, `sign_in_count` int(11) DEFAULT 0, `current_sign_in_at` datetime, `last_sign_in_at` datetime, `current_sign_in_ip` varchar(255), `last_sign_in_ip` varchar(255), `name` varchar(255), `created_at` datetime, `updated_at` datetime) ENGINE=InnoDB
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
I'm following a tutorial and have quite a hard time understanding why this happens. Can anyone explain what is going on?
In your create_users migration (APP_ROOT/db/migrate/..), add drop_table :users right before create_table :users and run rake db:migrate. It will remove the users table before recreating it. You can remove that line of code after running this migration so it doesn't give you errors later on. Just a small fix if you dont have UI access to a database (on heroku, for example).
You need to drop that table from the sql lite console (You will lost all the data contained in it)
Access the sql lite console, type in terminal
mysql <DB NAME HERE>
Drop table (dont forget the last ; (semicolon))
drop table table_name;
run db:migrate again
bin/rake db:migrate
Hope it helps, it worked for me
If you wanna play safe and don't want to lose any data then you can check if the table exists in your database.
class DeviseCreateUsers < ActiveRecord::Migration
def up
if table_exists?(:users)
# update or modify columns of users table here accordingly.
else
# create table and dump the schema here
end
end
def down
# same approach goes here but in the reverse logic
end
end
The migration is trying to create a table that already exists in your database.
Try to remove the user table from your database. Something went wrong with you migration process. You should also compare your schema.rb version with your db/migrate/*.rb files.
Clarification:
It seems that many SO users don't agree with my reply, either because they consider it inaccurate or not recommended.
Removing a table is always destructive, and I think that everyone understands that.
I should have mentioned add_column, since the table was being created in another migration file.
If you know the database was created properly, you can just comment out the creation part of the migration code. For example:
Class ActsAsVotableMigration < ActiveRecord::Migration
def self.up
# create_table :votes do |t|
#
# t.references :votable, :polymorphic => true
# t.references :voter, :polymorphic => true
#
# t.boolean :vote_flag
#
# t.timestamps
# end
#
# add_index :votes, [:votable_id, :votable_type]
# add_index :votes, [:voter_id, :voter_type]
end
def self.down
drop_table :votes
end
end
If the table was created, but later commands weren't completed for some reason, you can just leave the later options for example:
Class ActsAsVotableMigration < ActiveRecord::Migration
def self.up
# create_table :votes do |t|
#
# t.references :votable, :polymorphic => true
# t.references :voter, :polymorphic => true
#
# t.boolean :vote_flag
#
# t.timestamps
# end
add_index :votes, [:votable_id, :votable_type]
add_index :votes, [:voter_id, :voter_type]
end
def self.down
drop_table :votes
end
end
If you don't have any significant data in your database to preserve however you can just have it drop the table and all the data and create it fresh. For example (notice the "drop_table :votes", in the self.up):
class ActsAsVotableMigration < ActiveRecord::Migration
def self.up
drop_table :votes
create_table :votes do |t|
t.references :votable, :polymorphic => true
t.references :voter, :polymorphic => true
t.boolean :vote_flag
t.timestamps
end
add_index :votes, [:votable_id, :votable_type]
add_index :votes, [:voter_id, :voter_type]
end
def self.down
drop_table :votes
end
end
Don't delete tables. Data > migrations!
The version of the database already reflects the changes the error-causing migration is trying to add. In other words, if the migration could be skipped, then everything would be fine. Check the db_schema_migrations table and try inserting the version of the erroneous migration (e.x, 20151004034808). In my case this caused subsequent migrations to execute perfectly and everything seems fine.
Still not sure what caused this problem.
If your app is new and you don't care about the data in your database, simply:
rake db:reset
I think this is an issue unique or more common to mysql in rails, possible having to do with the mysql2 gem itself.
I know this because I just switched from sqlite to mysql and just started having this problem systematically.
In my case, I simply commented out the code that had already run and ran the migration again (which I'm not adding more detail to because it looks like the guy above me did that).
I had a similar problem when trying to add Devise authentication to an existing Users table.
My solution: I found that I had two migrate files, both trying to create the Users table. So rather than deleting the table (probably not the best habit to form), I commented out the first (original) migrate file that created the Users table and then left the Devise migrate file as-is. Re-ran the migration and it worked fine.
As it turns out, the Devise file wasn't causing the problem; I can see that it is "changing" the table, not "creating it", which means that even without the devise installation, a db:migrate probably would have caused the same issue (though I haven't tested this).
If you want to keep your data, rename the table, but do it in the migration to save time, then remove it once the migration has ran.
Place at the top part of the up section of the migration file.
rename_table :users, :users2

Problems with rake db:migrate

First
ruby script/generate model Buyer id:integer name:string
after generating Buyer model, I did
rake db:migrate
it was working fine.
After 1 day I have executed below command
ruby script/generate model Seller id:integer seller_name:string
after generating Seller model, I did
rake db:migrate
I got an error, that Buyer table is already exists. why? we have different timestamp file.
class CreateBuyer < ActiveRecord::Migration
def self.up
create_table :buyer do |t|
t.string :name
t.text :description
t.decimal :price
t.integer :seller_id
t.string :email
t.string :img_url
t.timestamps
end
end
def self.down
drop_table :ads
end
end
and another one is
class CreateSellers < ActiveRecord::Migration
def self.up
create_table :sellers do |t|
t.integer :nos
t.decimal :tsv
t.decimal :avg_price
t.timestamps
end
end
def self.down
drop_table :sellers
end
end
I used Rails 2.3.11 and rake 0.8.7
Are you sure there were no errors generated when you ran the first migration? If an error is encountered while running a migration, the parts that were already run will still be in the database, but schema_migrations won't be updated with the migration timestamp. Therefore, the next time you try to run migrations, it'll try to re-run the first part of the failed migration, which will generate errors since it's already been run.
Updated: If you look in the error output you added (by the way, please add to the question rather than a comment, so it's formatted and the whole thing is included) you can see that the first Execute db:migrate is running the migration CreateBuyer. This confirms that your migration did not complete the first time you ran it or has since been unsuccessfully rolled back. To fix this, manually drop the buyer table, then rerun your migrations.
As a note, there's at least a couple issues in your CreateBuyers migration:
The table name should be buyers (plural) rather than buyer (singular)
The down part of the migration is dropping the table ads instead of buyers
The second problem there could explain why you're having trouble running migrations now, actually. If you rolled back the CreateBuyers migration, it would have dropped your ads table and left buyers in place.

Resources