Am I correct in saying that the db/schema.rb file should be pulling from the db/migrate files on rake db:migrate? I am running a rake db:migrate and it is adding a table that isn't defined in the migrate, nor the models. Any ideas?
Migrate Files (just one):
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :email
t.string :hashed_password
t.timestamps
end
end
end
Resulting Schema after rake:
ActiveRecord::Schema.define(:version => 20121113214159) do
create_table "user_categories", :force => true do |t|
t.string "title"
t.string "description"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "users", :force => true do |t|
t.string "email"
t.string "hashed_password"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
end
I had added a user_categories scaffolding earlier, but incorrectly so I destroyed it. Not sure where I went wrong in destroying parts...
If you don't have any important data on your db, you could run rake db:drop then rake db:create. Then run rake db:migrate and it should update your schema clean.
It's important to note that rake db:migrate will poll your database for its current state (separate of migrations) and update schema.rb accordingly. If you go into SQL command line and add a table, for example, and then run rake db:migrate, schema.rb will reflect that new table whether there's a migration or not.
Could be that your forgot to define environment variables.
Open Gemfile and verify that you don't use the sqlite gem for your environment
Type the rake db:drop then rake db:drop commands if as output you receive empty string probably you forgot to setup environment variables
Checkout the config/database.yml file and find places where you could use them. You should find something like that: database: <%= ENV["<DB_NAME"] %>
Ensure that your variables has been set before. If you use the dotenv or figaro gems, probably you forgot to create appropriate file or define variables there
Related
I'm using Rails 4.2.6 and have strange error (learning rails with the HeadFirst book, project and directory name - "mebay"):
I need to create project uses only "read" of CRUD - so I run:
~/mebay $ rails generate model ad name:string description:text price:decimal seller_id:integer email:string img_url:string
Running via Spring preloader in process 8400
invoke active_record
identical db/migrate/20161018144410_create_ads.rb
identical app/models/ad.rb
invoke test_unit
identical test/models/ad_test.rb
identical test/fixtures/ads.yml
and here comes my db/migrate/20161018144410_create_ads.rb:
class CreateAds < ActiveRecord::Migration
def change
create_table :ads do |t|
t.string :name
t.text :description
t.decimal :price
t.integer :seller_id
t.string :email
t.string :img_url
t.timestamps null: false
end
end
end
(looks pretty ok for me, basing on earlier projects)
Then, as I understand, I need to create database (i use sqlite):
~/mebay $ rake db:migrate
but after that, my development.sqlite3 remain empty
what am i doing wrong?
You actually didn't do anything wrong. Look in db/schema.rb and if you see this then you're database is setup properly:
ActiveRecord::Schema.define(version: 20161019035406) do
create_table "ads", force: :cascade do |t|
t.string "name"
t.text "description"
t.decimal "price"
t.integer "seller_id"
t.string "email"
t.string "img_url"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
If you're getting an error that the table already exists, you can do the following:
first add a down method to your migration file that you used to generate the ads table. The down method would look like this:
def down
drop_table :ads
end
Then run rake db:migrate:down VERSION=version_number where the version_number is the timestamp in the name of the migration file. This will remove the table from the database. Then change the name of the change method to up. Save the file and run rake db:migrate:up to create the table again.
How about run rake db:create first and then run rake db:migrate
I have a db with columns (name, path). Now I have a migration file that changes the columns to be (name, pathorig, pathjson, scramble).
Doing rake db:reset and rake db:migrate doesn't update the table. Why can this happen?
my migration file:
class CreateUploads < ActiveRecord::Migration
def change
create_table :uploads do |t|
t.string :name
t.string :pathorig
t.string :pathjson
t.string :scramble
t.timestamps
end
end
end
The schema.rb file:
ActiveRecord::Schema.define(version: 20131029072745) do
create_table "uploads", force: true do |t|
t.string "name"
t.string "path"
t.datetime "created_at"
t.datetime "updated_at"
end
end
Difference between rake db:migrate db:reset and db:schema:load has a great explanation of what the various rake db:* commands do.
Because rake db:reset performs a db:schema:load, it's loading the old columns from your table, rather than calling db:migrate, this is why your migration isn't being run.
Consider writing a migration that changes the names of those columns, rather than re-creates an existing table, or manually run rake db:drop; rake db:create db:migrate
I have strange problem with properly preparing test database in Rails3.
In schema.rb I have:
create_table "sites", :force => true do |t|
t.string "ldap_dn", :null => false
t.string "address"
t.string "phone"
t.string "description"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
then in one of my migrations I have:
change_column :sites, :id, :string, :limit => 255, :primary_key => true
Now, in development database after rake db:migrate I have
id VARCHAR(255) PK
BUT in test database after rake db:test:prepare I have
id INT(11) PK AI
In the log file (test.log) I can see all migrations are executed.
I use:
rails 3.2.13
mysql for both dev and test database
Is this some kind of bug?
Edit:
I meant development database. Sorry.
Check in your db/schema.rb what you have there. The rake tasks db:test:prepare (and db:test:load) just recreate the database from your schema file, which can become inconsistent with the schema_migrations table in certain cases (when you run migration and then change it during development).
If you have id defined as an INT in your schema and you have no pending migrations in your dev environment then you need to rerun your migration with rake db:migrate:redo.
You specifically say production database, so that makes me wonder if you ran the migrations in your development environment as well. Imho rake db:test:prepare creates a copy of your development database, so make you sure all your migrations have also run in development (we had a problem with that on our build machine, where there was no development database). To be sure that your test-database is created for the current schema, you could also use
RAILS_ENV=test rake db:reset
This will drop and recreate the database using the schema.rb file.
For Rails 3.2 I have written this migration to rename the column name as seen in the migration
class RenameKpiColumn < ActiveRecord::Migration
def change
rename_column(:key_performance_intervals, :kpi_id, :key_performance_interval_id)
end
end
And then I said bundle exec rails db:migrate
If I go to Schema.rb I see this for that table, so looks likes it picked the new column name from Migration:
create_table "key_performance_intervals", :force => true do |t|
t.integer "key_performance_interval_id"
t.integer "interval"
t.integer "interval_unit"
t.decimal "count"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
But if I open the pgAdmin tool and look at the tables and column names in there, it is still using the old column name of kip_id .
Is there any step I am missing?
Since migrating the database gives no output, it seems that the migrations ran fine. Just restart pAdmin and the changes should be reflected there.
To also prepare your test database, run
$ rake db:test:prepare
I have a sqlite3 db in a rails app with the following schema
ActiveRecord::Schema.define(:version => 20100816231714) do
create_table "comments", :force => true do |t|
t.string "commenter"
t.text "body"
t.integer "post_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "posts", :force => true do |t|
t.string "name"
t.string "title"
t.text "content"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "tags", :force => true do |t|
t.string "name"
t.integer "post_id"
t.datetime "created_at"
t.datetime "updated_at"
end
end
I began with a Post :has_many relationship with tags so each tag has a post_id reference.
I now want to change this relationship to a 'has_and_belongs_to_many', I know i have to create the joins table etc.... this isn't a problem and is working
The problem comes in when i try remove the post_id form the tags table. My migration looks like this:
class RemoveFieldsToTags < ActiveRecord::Migration
def self.up
remove_column :tags, :post_id
end
def self.down
add_column :tags, :post_id, :references
end
end
When I run rake db:migrate and rake db:migrate:up VERSION= Nothing happens when I run rake db:migrate:down VERSION= I get column:
SQLite3::SQLException: duplicate column name: post_id: ALTER TABLE "tags" ADD "post_id" references
Any one know whats going on?
It sounds as if Rails thinks your DB is up to date (given that nothing happens when you run db:migrate). You can get into this state if you've modified your migration after applying it (common during development).
Have you tried running db:migrate on a fresh db (note this will wipe your database)?
rake db:drop db:create db:migrate
Like avaynshtok mentions above, it sounds like rails thinks your migrations are up to date (as in, they have all been applied), but to you they are not (the post_id column is still on the tags table).
A common 'workaround' to deal with this situation without having to wipe your database is commenting out the 'down' method of your migration and running
rake db:migrate:redo
Given the 'down' is commented out, it won't try to add the column again, so it will proceed to reapply the 'up' method, removing your 'post_id' column. You can then remove the comment on the 'down' method and it should all be good.
PS. You might want to look into using a 'has_many :through' type of relationship instead of 'has_and_belongs_to_many' as well.
I had a similar problem to the op, but had to manually delete the databases and then run
rake db:create db:migrate
rake db:migrate:redo
and
rake db:drop
did not work for me as it kept saying "db/test.sqlite3 already exists".