Ruby on Rails - sqlite 3 rake migrations not updating the database - ruby-on-rails

I am using RoR (3.2.2) and SQLite 3 (1.3.5). When I initially generate a model I am able to successfully create a database. However, whenever I try to use the migration generator it appears to not have any issues in the command line (no errors), but when I check the database nothing has updated or changed.
For example, I create this database:
$ rails generate model User name:string email:string
db/migrate/[timestamp]_create_users.rb
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :name
t.string :email
t.timestamps
end
end
end
And I run a migration:
$ bundle exec rake db:migrate
So far so good, I check my database using SQLite Database Browser and everything looks as it should.
Then if I want to add an index:
$ rails generate migration add_index_to_users_email
db/migrate/[timestamp]_add_index_to_users_email.rb
class AddIndexToUsersEmail < ActiveRecord::Migration
def change
add_index :users, :email, unique: true
end
end
I run a migration:
$ bundle exec rake db:migrate
And command line gives me the following:
bundle exec rake db:migrate
== AddIndexToUsersEmail: migrating ===========================================
== AddIndexToUsersEmail: migrated (0.0000s) ==================================
However, when I check my database using SQLite Database Browser it isn't updated. I get the same results if I try to add new columns to the table, etc. The only way I have been able to do migrations is manually updating the database using the SQLite Database Browser. Any help as to why it is not working through Rails and the command line would be greatly appreciated.
Here is my gemfile:
source 'https://rubygems.org'
gem 'rails', '3.2.2'
gem 'bootstrap-sass', '2.0.0'
group :development, :test do
gem 'sqlite3', '1.3.5'
gem 'rspec-rails', '2.8.1'
gem 'annotate', '~> 2.4.1.beta'
end
group :assets do
gem 'sass-rails', '3.2.4'
gem 'coffee-rails', '3.2.2'
gem 'uglifier', '1.2.3'
end
gem 'jquery-rails', '2.0.0'
group :test do
gem 'capybara', '1.1.2'
end
group :production do
gem 'pg', '0.12.2'
end
Database.yml
development:
adapter: sqlite3
database: db/development.sqlite3
pool: 5
timeout: 5000
test:
adapter: sqlite3
database: db/test.sqlite3
pool: 5
timeout: 5000
production:
adapter: sqlite3
database: db/production.sqlite3
pool: 5
timeout: 5000
Example of successfully adding a column:
rails generate migration add_password_digest_to_users password_digest:string
invoke active_record
create db/migrate/20120318235656_add_password_digest_to_users.rb
$ subl db/migrate/[timestamp]_add_password_digest_to_users.rb
$ bundle exec rake db:migrate
== AddPasswordDigestToUsers: migrating =======================================
-- add_column(:users, :password_digest, :string) -> 0.0008s
== AddPasswordDigestToUsers: migrated (0.0009s) ==============================
Example of unsuccessfully adding a column:
$ rails generate migration add_remember_token_to_users
invoke active_record
create db/migrate/20120319010623_add_remember_token_to_users.rb
$ subl db/migrate/[timestamp]_add_remember_token_to_users.rb
$ bundle exec rake db:migrate
== AddRememberTokenToUsers: migrating ========================================
== AddRememberTokenToUsers: migrated (0.0000s) ===============================
Notice when it fails to update the database the migration time is zero. I'm not sure what I am doing wrong. Thanks in advance for any suggestions.

I solved the problem undoing the last migration with
rails destroy migration add_index_to_users_email
Then I closed my terminals to ensure that all db connections were closed, then I run
rake db:reset
Finally, running the same commands again
rails generate migration add_index_to_users_email
Updating the file with the same content and running
rake db:migrate
All the same commands and files that were not working before now worked at all (for me).
I hope this works for you as well.

I think what happens is you get the syntax slightly wrong (it's insanely tricky) then you get an empty migration which doesn't do anything.
I would double check that the actual migration file has add column. I often end up manually putting the actual change (or up/down) in.
As t Harrison says, adding an index is more subtle - as you sure it doesn't get added if you refresh the sqlite borwser. The examples you gave that worked... are to add columns...

The output you posted from the add index example shows that the migration is indeed running ... but you report it's not actually doing anything. Try bundle exec rake:db rollback (with optional STEP=n to go more than one step back). This really should "just work", and a case of an index might be a little subtle -- try adding a column or something (which you said you have done, but, just to be sure). Does it really not work? How can you tell?

Related

Heroku Rails - 500 Internal Server Error

When I post something in my Rails app (locally), it works perfectly. However, when I deploy it on Herokuapp, it breaks. Here is what I have:
#Gemfile
# Use sqlite3 as the database for Active Record
gem 'sqlite3', group: :development
gem 'pg', '0.18.1', group: :production
gem 'rails_12factor', group: :production
#database.yml
production:
<<: *default
adapter: postgresql
database: db/production.sqlite3
I then proceeded to deploy my app to Heroku like this:
git add .
git commit -m "comment"
git push heroku master
heroku run rake db:migrate
heroku run rake db:seed
I've checked my version using the following:
heroku run rake db:version
>> Current version: 20171103035018
rake db:version
>> Current version: 20171103035018
Finally, here is my controller where I perform a create action:
#suggestions_controller.rb
def create
#suggestion = Suggestion.new(suggestion_params)
if #suggestion.save
flash[:notice] = "Suggestion successfully posted!"
redirect_to root_path
else
flash[:error] = "Suggestion failed to post!"
redirect_to root_path
end
end
private
def suggestion_params
params.require(:suggestion).permit(:suggester, :ip, :suggestion_type, :title, :body)
end
I tried this on my localhost and it creates just fine, but when I deploy it on Heroku, it displays this error:
I'm pretty certain I did everything correctly and I have no idea what's breaking here.
Thanks for any help.
Edit: I just got a lead to the problem. It says that my created_at is null.
ActiveRecord::NotNullViolation (PG::NotNullViolation: ERROR: null value in column "created_at" violates not-null constraint
I'm researching on the web now to see how I can fix this problem.
Well, you should take a look at your logs. Heroku documented their logging here: https://devcenter.heroku.com/articles/logging
From your description, it may be something about your database setup, e.g. wrong database.yml.
If the logs don't help you, please fix the indentation of your database.yml posted above.
I figured out the problem. It was indeed this particular error message:
ActiveRecord::NotNullViolation (PG::NotNullViolation: ERROR: null value in column "created_at" violates not-null constraint
I had to add this line of code to my suggestions_controller.rb
def create
Suggestion.record_timestamps = true; #added this line of code
... #other logic
end
When I upvote and downvote a post, I don't want it to update the timestamps such as this:
def upvote
Suggestion.record_timestamps = false;
... #other logic
end
I redeployed my app and it works fine now.

Require a gem in all migrations

I have this gem in my gemfile (gem "lhm", "~> 2.2.0", require: false) that I want required in all migrations. Behavior similar to that of requiring spec_helper in all spec files.
I considered doing something with bin/rails or bin/rake but I don't want it required in all tasks, just migrations. Ie. rake db:migrate or the now alias rails db:migrate
As you probably don't have all the migrations using lhm I would suggest adding require "lhm" only to the migrations you're using. But to answer your question you could use rake's enhance method:
add the below to lib/tasks/something.rake:
namespace :load do
namespace :lhm do
desc "This just loads lhm"
task lhm: :environment do
require "lhm"
end
end
end
Rake::Task['db:migrate'].enhance(['load:lhm'])
As an example see here

Don't know how to build task 'db:seed_fu'

I have just added the seed-fu gem to my app for seeding my test-database:
group :test do
gem 'seed-fu'
end
I made a custom rake task (in /lib/tasks/db.rake) for seeding only my test-database:
namespace :db do
desc "seed_fu only in test-database"
task seed_fu_test: :environment do
Rails.env = 'test'
puts "Seeding will be made in test-base ONLY!"
Rake::Task["db:seed_fu"].execute
end
end
If I do rake -T | grep seed then my new custom-made task is shown amongst other seed-tasks:
rake db:seed # Load the seed data from db/seeds.rb
rake db:seed_fu # Loads seed data for the current environment
rake db:seed_fu_test # seed_fu only in test-database
Now when I do rake db:seed_fu_test I get
rake aborted!
Don't know how to build task 'db:seed_fu'
But when I do
rake db:seed_fu RAILS_ENV='test'
then seed_fu seeds my test-database well.
Figured it out- the problem was in my Gemfile. Because I added the seed-fu gem into test-group then in development-environment, which was my default for running also the rake db:seed_fu_test task, the seed_fu gem was not seen.
Therefore when moving gem 'seed-fu' line into my :development-group in Gemfile, the problem was solved.

Active_admin running an error when run rake db:migrate

I'm trying to install ActiveAdmin under Rails 4 to generate my admin panel.
I added the gem and installed with the below commands:
gem 'activeadmin', github: 'gregbell/active_admin'
bundle install
rails g active_admin:install # creates the AdminUser class
rails g active_admin:install User # uses an existing class
But when I try to migrate I get an error:
$ rake db:migrate
== AddDeviseToAdminUsers: migrating ==========================================
-- change_table(:admin_users)
rake aborted!
An error has occurred, this and all later migrations canceled:
SQLite3::SQLException: duplicate column name: email: ALTER TABLE "admin_users" ADD "email" varchar(255) DEFAULT '' NOT NULL/usr/local/rvm/gems/ruby-2.0.0-p247/gems/sqlite3-1.3.8/lib/sqlite3/database.rb:91:in `initialize'
As mentioned in issue 753 on github I changed the AddDeviseToAdminUsers migration from change_table to create_table but that results in this error:
== AddDeviseToAdminUsers: migrating ==========================================
-- create_table(:admin_users)
rake aborted!
Can anyone help please?
The exception you're seeing is due to a migration conflicting with your existing database structure. Your admin_users table already contains an "email" column, which is why you're seeing the error duplicate column name: email.
You should only run the active_admin:install generator once. Running the ActiveAdmin setup with a clean application should only involve the following:
# Add the BETA gem with Rails 4 support. The ActiveAdmin master
# branch is still in heavy development.
gem 'activeadmin', github: 'gregbell/active_admin'
# Bundle
bundle install
# Setup ActiveAdmin
rails g active_admin:install
For more advanced cases, where you already have an ActiveRecord model for an admin user then you'd use this variant of the generator: rails g active_admin:install MyAdminUser

PGError: ERROR: relation "table_name" does not exist

I am trying to push a simple app up to heroku and run:
heroku rake db:migrate
But I get the following error:
rake aborted!
PGError: ERROR: relation "posts" does not exist
: SELECT a.attname, format_type(a.atttypid, a.atttypmod), d.adsrc, a.attnotnull
FROM pg_attribute a LEFT JOIN pg_attrdef d
ON a.attrelid = d.adrelid AND a.attnum = d.adnum
WHERE a.attrelid = '"posts"'::regclass
AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum
Tasks: TOP => db:migrate => environment
(See full trace by running task with --trace)
My migration looks like this:
class CreatePosts < ActiveRecord::Migration
def change
create_table :posts do |t|
t.string :source
t.string :tweetid
t.string :pure
t.string :media
t.string :destination
t.datetime :time
t.timestamps
end
end
end
And, after referring to another SO answer, I have included the following in my Gemfile:
# Gems used only for assets and not required
# in production environments by default.
group :assets do
gem 'sass-rails', '~> 3.1.4'
gem 'coffee-rails', '~> 3.1.1'
gem 'uglifier', '>= 1.0.3'
gem 'pg'
end
Thank you in advance for any help!
--- UPDATE ---
The main reason I am confused is that this all works locally, just not when I run the migration on heroku.
Here is the error I get now:
rake aborted!
Please install the postgresql adapter: `gem install activerecord-postgresql-adapter` (pg is not part of the bundle. Add it to Gemfile.)
I have been looking at this question:
Heroku error when launch rails3.1 app missing postgres gem
I am almost-certain my database.yml should not look like this (seeing as I need to be running postgresql!!!):
# SQLite version 3.x
# gem install sqlite3
#
# Ensure the SQLite 3 gem is defined in your Gemfile
# gem 'sqlite3'
development:
adapter: sqlite3
database: db/development.sqlite3
pool: 5
timeout: 5000
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
adapter: sqlite3
database: db/test.sqlite3
pool: 5
timeout: 5000
production:
adapter: sqlite3
database: db/production.sqlite3
pool: 5
timeout: 5000
Serious apologies for the nubishness here. Thank you for your help in advance!
Also tried this link: Uploading to Heroku DB rake:migrate problem
create_table :posts
Didn't you forget the s? The table names should be plural.
I just ran: bundle exec rake db:migrate and it worked
I had a similar problem, but it wasn't caused by the migration or the Gemfile. I had 4 models setup in a polymorphic relationship. Removing the statement
belongs_to :assetable, :polymorphic => true, :dependent => :destroy
and removing the subclass' acts_as_* declarations was enough to enable the db:migrate to successfully complete. I then added back the statements in the models and everything worked great. I'm not exactly sure why this is the case, but if you are in a similar situation this may help temporarily until a better solution presents itself.
My situation is polymorphic multi-table inheritance scheme between one parent and 3 objects using http://mediumexposure.com/multiple-table-inheritance-active-record/ as a baseline.
If you're using ActiveAdmin, whichever table PG says doesn't exist, comment out the contents of that ActiveAdmin rb file.
For example, for this case PGError: ERROR: relation "posts" does not exist, comment out the entire contents of app/admin/posts.rb, then uncomment after you've done your migrations.
Robin probably has it right but just in case...
Check the filename/timestamps on your migrations. These get run in sequence. I had an issue where a generator that made my migrations was putting the foreign table first...I switched the file names and it worked.
It's a long shot but I thought I'd put that out there.
In my case, I was doing rename_table in my migration, after having already modified my model name to reflect the new table name. I had moved User into User::User. The users table needed to be renamed to user_users, so my migration looked like
class RenameUsersTableWithPrefix < ActiveRecord::Migration
def up
rename_table :users, :user_users
end
def down
rename_table :user_users, :users
end
end
Instead of
app/models/user.rb
I now had
app/models/user.rb
app/models/user/user.rb
with the latter containing the User::User model, and the former containing simply
module User
def self.table_name_prefix
"user_"
end
end
It was this class method in the newly added User module that was giving me the PGError when running rake db:migrate like the OP had. Temporarily removing this class method while I ran my migration allowed the migration to run smoothly.
I was having the same problem. I ran heroku run rake db:migrate and that solved the problem.

Resources