rails destroy scaffold leaves back table - ruby-on-rails

I created a new scaffold using the command:
rails generate scaffold level
But then I destroyed it using the command
rails destroy scaffold level
And then again added it back using the command
rails generate scaffold level question:string answer:string prev_q:integer next_q:integer
But now when I try rake db:migrate then I get the following error
SQLite3::SQLException: table "levels" already exists: CREATE TABLE "levels" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "question" varchar(255), "answer" varchar(255), "prev_q" integer, "next_q" integer, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL)
My migrate/create_level.rb is
class CreateLevels < ActiveRecord::Migration
def change
create_table :levels do |t|
t.string :question
t.string :answer
t.integer :prev_q
t.integer :next_q
t.timestamps
end
end
end
But my schema.rb is:
create_table "levels", :force => true do |t|
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
I want to know that how can I update the levels table in the schema. Also I would like to know that why doesn't the table get deleted when I destroy the scaffold. Do I need to run another command to do it?

Using destroy scaffold does not run the rollback to the migration. The correct way of doing it would have been
rake db:rollback
rails destroy scaffold level
now, as you don't have that other migration anymore, you cannot roll it back. You'll need to delete that table manually:
rails dbconsole
DROP TABLE levels;

What I had to do was:
First I followed the steps specified by #Alex Siri.
But after doing that using
rake db:migrate
Did not add the values question,answer etc to the table, so I did the following steps
I again deleted the scaffold using the command
rails destroy scaffold level
After that I again created the scaffold using the command:
rails generate scaffold level question:string answer:string prev_q:integer next_q:integer
Finally I ran migration using
rake db:migrate
This solved my problem. I wrote all the steps so that if anyone else has the same problem then they can easily solve it.

Related

Rails remove column that has no data type

In my Rails 5 application I've accidentally created a column with no data type. Database is SQLite.
create_table "students", force: :cascade do |t|
t.integer "club_id"
t.string "email"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "picture"
t.integer "payment_plan_id"
t. "activity"
t.index ["club_id"], name: "index_students_on_club_id"
end
When I attempt rails db:rollback I get this error:
Rhys-MacBook-Pro:classmaster Rhys$ rails db:rollback == 20161011105423 AddActivitiesRefToStudents: reverting =======================
-- remove_column(:students, :activity, :reference)
rails aborted! StandardError: An error has occurred, this and all later migrations canceled: undefined method `to_sym' for nil:NilClass
I've tried running this migration:
class RemoveColumn < ActiveRecord::Migration
def up
execute "ALTER TABLE students DROP COLUMN activity";
end
end
But I think SQLite doesn't support dropping columns. Is there a fix for this?
I am assuming it is the activity column you want to drop based on it not having a type in that file, if it is a different column then just change the column name below.
What you want to do is drop a column from the table, which you absolutely can do. In the command line do something like the line below (or exactly like the line below) to create the migration to drop the column.
rails g migration drop_activity_column_from_students
Then open that file, the method inside should be this.
def change
remove_column :students, :activity
end
Then run
rake db:migrate
and you should see that one column get dropped from the table.
You can find a ton of information here about migrations, if that is something you want to learn more about.
I had the same problem, and after trying various migrations and running rails db:reset without success, I just deleted my schema.rb file and ran rails db:migrate, which rebuilt my schema from scratch without the column that didn't have a data type. Just make sure that none of your migrations contain the addition of the "activity" column, so you don't repeat the problem.
Try to change the type of the column by:
rails g migration FixActivityTypeStudents
Then on the migration add this part.
def change
change_column :students, : activity, :string
end

Reset Rails Database

I am in a world of mess. I had some issues with the mailboxer gem and the tables it created in my schema, so i commented the offending attributes and reset my database. Nothing changed when I ran db:migrate, so I dropped the table, created it anew and reran the migration. The schema has not updated to reflect the attributes which had been commented out. Any ideas as to why? I now have an error message when trying to rake db:migrate which aborts and says that:
PG::UndefinedTable: ERROR: relation "roles" does not exist : ALTER TABLE "roles" DROP "user_id"
My schema has a roles table which includes the following attributes:
create_table "roles", force: true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "user_id"
end
I have a migration in my file which is intended to remove the user_id:
class Removeuidfromrole < ActiveRecord::Migration
def change
remove_column :roles, :user_id, :integer
end
end
I have no idea why it is aborting with an error telling me to remove the user id, when I have a migration to do just that. Further, why doesn't the schema update to reflect the recreated db?

Adding/Updating column in a Model using RubyMine

I'm working on a web app that basically interacts with a db table through a form. Recently I had to make some changes which resulted in me adding another column to the db table. I'm using RubyMine for developing and can't figure out how to update the model so that it contains the new column. I've added it inside the model as so:
class Student < ActiveRecord::Base
attr_accessible :f_name, :floor_pref, :l_name, :is_active
validates_presence_of :f_name, :floor_pref, :l_name
end
I've also added it inside the schema.rb:
ActiveRecord::Schema.define(:version => 20130620140537) do
create_table "students", :force => true do |t|
t.string "f_name"
t.string "l_name"
t.string "floor_pref"
t.boolean "is_active"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
end
And also inside the migrate as so:
class CreateStudents < ActiveRecord::Migration
def change
create_table :students do |t|
t.string :f_name
t.string :l_name
t.string :floor_pref
t.boolean :is_active
t.timestamps
end
end
end
Problem is when I run the rails console and look up my model object it doesn't show the new column that I have added (:is_active). It only shows the old columns:
>> Student
Loading development environment (Rails 3.2.13)
Switch to inspect mode.
Student(id: integer, f_name: string, l_name: string, floor_pref: string, created_at: datetime, updated_at: datetime)
What am I missing?
What you should do know, is to delete all changes you have added to model app/models/Student.rb and to db/schema.rb
Then you should go to your terminal/console and type
$ rails g migration add_column_name_to_student column_name:type
This command will create new file in db/migrate/ folder.
$ rake db:migrate
After updating your database schema with rake db:migrate. Go to your app/models/Student.rb and add new column_name into attr_accessible, if you want to setup this value by form.
This whole procedure has nothing to do with your IDE.
Here are some other resources, where you can get information how to add new column to models.
Generate Rails Migrations That Automagically Add Your Change
Rails 3: How to add a new field to an existing database table
You should definitely avoid adding new columns the way you did that. It's messy and makes your code difficult to maintain.
This is not the correct way to add a new column to your table. You want to open your console and run the following command your after is rails g migration add_column_name_to_table column_name:type then run a bundle exec rake rake db:migrate. Its not good to just shove things in.
Ex: If I want to add the postedon column to posts table, then:
rails g migration AddPostedOnToPosts posted_on:date
This will add column in your migration file automatically.

Migration changes show in Schema file but not in the DB

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

remove_column not removing column or giving any errors in rails

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".

Resources