I am willing to create a new model i.e a new table for my application. I have already a table existing for my application and I want to create a new one. But I am facing problem when running rake db:migrate command after executing the following command for creating a new table.
rails g model information age:string name:string
while running rake db:migrate command the system is showing the following error message:
don't know how to build task db:migrate
And no table is created ultimately. I am using Postgresql.
A migration is generated as :
class CreateInformation < ActiveRecord::Migration
def change
create_table :information do |t|
t.string :age
t.string :name
t.timestamps null: false
end
end
end
And no change in the schema.rb file .
I Don't think the command you are using matches any rails command generator
rails g information age:string name:string
if you are generating model it should be
rails g model Information age:string name:string
I should be capital(read Rails Conventions)
and if you are trying to create a migration then it should be
rails g migration information age:string name:string
and then you run rake db:migrate to make it run.
To create a model, you need to write model after rails g.
Make sure you're inside your rails app folder. If you have an existing table with the same name you might want to get rid of it first by dropping it.. Then create again.
rails g model Information age name
#age and name will be string by default, so you can omit writing string
Are you running rails5? You error is this:
don't know how to build task db:migrate
For rails 5 there is no rake tasks (changed to rails) You should do
bin/rails db:migrate
I have a 'question' model in Subdirectory Exceed::Question.
now I want to add migration for Question model, so I run
rails g migration AddImageToExceedQuestions
after that when I run `rake db:migrate
Its show error -
Mysql2::Error: Table 'bs_development.questions' doesn't exist: ALTER TABLE `questions`
In my database question model save as exceed_question.
I also try rails g migration AddImageToQuestions and rails g migration AddImageToExceed::Questions but get same error.
How I can create migration for model that in subdirectory.
In ActiveRecord migrations are not actually tied to model classes. They simply modify the schema and database tables but do not care about if your models actually exist at all.
The rails generators are smart enough to recognize some forms such as rails g migration AddNameToFooBar name:string which would generate:
class AddNameToFooBar < ActiveRecord::Migration
def change
add_column :foo_bars, :name, :string
end
end
Rails will recognize that the part after to is a table name and snake case it. And then pluralize the last word if it is singular.
rails g migration add_name_to_foo_bar name:string creates an identical migration. The same with rails g migration add_name_to_foo_bars name:string except for the file & class name of the migration.
You can fix your issue by opening up the migration file and ensuring that it has the correct table
class AddImageToExceedQuestions < ActiveRecord::Migration
def change
add_column :exceed_questions, :image, :string # or binary
end
end
Note that your table should be named exceed_questions, tables in rails use the plural form of the table name.
I have a scaffold, but it fails because the text of the users is longer than string permits. So I would like to change the kind of data, rails g scaffold Dreams Dream:string for Dreams:text,
It is possible?
If you have already migrate, undo it:
rake db:rollback
rails destroy scaffold Dreams Dream:string
And redo it
rails generate scaffold Dreams Dream:text
rake db:migrate
You don't need to make rake db:rollback and rake db:migrate if you have just generated your scaffold.
If it is not your last migration, you can undo it with:
rake db:migrate:down VERSION=<version>
# version is the number of your migration file you want to revert
You can create a new migration:
rails generate migration change_dream_type_in_dreams
and open migration to use change_column
def self.up
change_column :dreams, :dream, :text
end
def self.down
change_column :dreams, :dream, :string
end
Finally, rake db:migrate.
First of all, the scaffold should be a singular noun like User and in your case, it should be Dream, Rails will not allow Dreams unless you pass --force-plural option.
Second, the column name should also be singular, though it can be plural, but rails convention in general is to have singular column names.
And yes, you are right!
rails g scaffold Dream dream:text
text is the option you are looking for. And if you do not specify anything with dream, Rails will take it as string.
I added a table that I thought I was going to need, but now no longer plan on using it. How should I remove that table?
I've already run migrations, so the table is in my database. I figure rails generate migration should be able to handle this, but I haven't figured out how yet.
I've tried:
rails generate migration drop_tablename
but that just generated an empty migration.
What is the "official" way to drop a table in Rails?
You won't always be able to simply generate the migration to already have the code you want. You can create an empty migration and then populate it with the code you need.
You can find information about how to accomplish different tasks in a migration here:
http://api.rubyonrails.org/classes/ActiveRecord/Migration.html
More specifically, you can see how to drop a table using the following approach:
drop_table :table_name
Write your migration manually. E.g. run rails g migration DropUsers.
As for the code of the migration I'm just gonna quote Maxwell Holder's post Rails Migration Checklist
BAD - running rake db:migrate and then rake db:rollback will fail
class DropUsers < ActiveRecord::Migration
def change
drop_table :users
end
end
GOOD - reveals intent that migration should not be reversible
class DropUsers < ActiveRecord::Migration
def up
drop_table :users
end
def down
fail ActiveRecord::IrreversibleMigration
end
end
BETTER - is actually reversible
class DropUsers < ActiveRecord::Migration
def change
drop_table :users do |t|
t.string :email, null: false
t.timestamps null: false
end
end
end
First generate an empty migration with any name you'd like. It's important to do it this way since it creates the appropriate date.
rails generate migration DropProductsTable
This will generate a .rb file in /db/migrate/ like 20111015185025_drop_products_table.rb
Now edit that file to look like this:
class DropProductsTable < ActiveRecord::Migration
def up
drop_table :products
end
def down
raise ActiveRecord::IrreversibleMigration
end
end
The only thing I added was drop_table :products and raise ActiveRecord::IrreversibleMigration.
Then run rake db:migrate and it'll drop the table for you.
Warning: Do this at your own risk, as #z-atef and #nzifnab correctly point out, Rails will not be aware of these changes, your migration sequence fill fail and your schema will be different from your coworkers'. This is meant as a resource for locally tinkering with development only.
While the answers provided here work properly, I wanted something a bit more 'straightforward', I found it here: link
First enter rails console:
$rails console
Then just type:
ActiveRecord::Migration.drop_table(:table_name)
And done, worked for me!
You need to to create a new migration file using following command
rails generate migration drop_table_xyz
and write drop_table code in newly generated migration file (db/migration/xxxxxxx_drop_table_xyz) like
drop_table :tablename
Or if you wanted to drop table without migration, simply open rails console by
$ rails c
and execute following command
ActiveRecord::Base.connection.execute("drop table table_name")
or you can use more simplified command
ActiveRecord::Migration.drop_table(:table_name)
rails g migration drop_users
edit the migration
class DropUsers < ActiveRecord::Migration
def change
drop_table :users do |t|
t.string :name
t.timestamps
end
end
end
rake db:migrate
The simple and official way would be this:
rails g migration drop_tablename
Now go to your db/migrate and look for your file which contains the drop_tablename as the filename and edit it to this.
def change
drop_table :table_name
end
Then you need to run
rake db:migrate
on your console.
I wasn't able to make it work with migration script so I went ahead with this solution. Enter rails console using the terminal:
rails c
Type
ActiveRecord::Migration.drop_table(:tablename)
It works well for me. This will remove the previous table. Don't forget to run
rails db:migrate
I think, to be completely "official", you would need to create a new migration, and put drop_table in self.up. The self.down method should then contain all the code to recreate the table in full. Presumably that code could just be taken from schema.rb at the time you create the migration.
It seems a little odd, to put in code to create a table you know you aren't going to need anymore, but that would keep all the migration code complete and "official", right?
I just did this for a table I needed to drop, but honestly didn't test the "down" and not sure why I would.
you can simply drop a table from rails console.
first open the console
$ rails c
then paste this command in console
ActiveRecord::Migration.drop_table(:table_name)
replace table_name with the table you want to delete.
you can also drop table directly from the terminal. just enter in the root directory of your application and run this command
$ rails runner "Util::Table.clobber 'table_name'"
You can roll back a migration the way it is in the guide:
http://guides.rubyonrails.org/active_record_migrations.html#reverting-previous-migrations
Generate a migration:
rails generate migration revert_create_tablename
Write the migration:
require_relative '20121212123456_create_tablename'
class RevertCreateTablename < ActiveRecord::Migration[5.0]
def change
revert CreateTablename
end
end
This way you can also rollback and can use to revert any migration
Alternative to raising exception or attempting to recreate a now empty table - while still enabling migration rollback, redo etc -
def change
drop_table(:users, force: true) if ActiveRecord::Base.connection.tables.include?('users')
end
You can't simply run drop_table :table_name, instead you can create an empty migration by running:
rails g migration DropInstalls
You can then add this into that empty migration:
class DropInstalls < ActiveRecord::Migration
def change
drop_table :installs
end
end
Then run rails db:migrate in the command line which should remove the Installs table
The solution was found here
Open you rails console
ActiveRecord::Base.connection.execute("drop table table_name")
ActiveRecord::Base.connection.drop_table :table_name
if anybody is looking for how to do it in SQL.
type rails dbconsole from terminal
enter password
In console do
USE db_name;
DROP TABLE table_name;
exit
Please dont forget to remove the migration file and table structure from schema
I needed to delete our migration scripts along with the tables themselves ...
class Util::Table < ActiveRecord::Migration
def self.clobber(table_name)
# drop the table
if ActiveRecord::Base.connection.table_exists? table_name
puts "\n== " + table_name.upcase.cyan + " ! "
<< Time.now.strftime("%H:%M:%S").yellow
drop_table table_name
end
# locate any existing migrations for a table and delete them
base_folder = File.join(Rails.root.to_s, 'db', 'migrate')
Dir[File.join(base_folder, '**', '*.rb')].each do |file|
if file =~ /create_#{table_name}.rb/
puts "== deleting migration: " + file.cyan + " ! "
<< Time.now.strftime("%H:%M:%S").yellow
FileUtils.rm_rf(file)
break
end
end
end
def self.clobber_all
# delete every table in the db, along with every corresponding migration
ActiveRecord::Base.connection.tables.each {|t| clobber t}
end
end
from terminal window run:
$ rails runner "Util::Table.clobber 'your_table_name'"
or
$ rails runner "Util::Table.clobber_all"
Helpful documentation
In migration you can drop table by:
drop_table(table_name, **options)
options:
:force
Set to :cascade to drop dependent objects as well. Defaults to false
:if_exists
Set to true to only drop the table if it exists. Defaults to false
Example:
Create migration for drop table, for example we are want to drop User table
rails g migration DropUsers
Running via Spring preloader in process 13189
invoke active_record
create db/migrate/20211110174028_drop_users.rb
Edit migration file, in our case it is db/migrate/20211110174028_drop_users.rb
class DropUsers < ActiveRecord::Migration[6.1]
def change
drop_table :users, if_exist: true
end
end
Run migration for dropping User table
rails db:migrate
== 20211110174028 DropUsers: migrating ===============================
-- drop_table(:users, {:if_exist=>true})
-> 0.4607s
the best way you can do is
rails g migration Drop_table_Users
then do the following
rake db:migrate
Run
rake db:migrate:down VERSION=<version>
Where <version> is the version number of your migration file you want to revert.
Example:-
rake db:migrate:down VERSION=3846656238
Drop Table/Migration
run:-
$ rails generate migration DropTablename
exp:- $ rails generate migration DropProducts
if you want to drop a specific table you can do
$ rails db:migrate:up VERSION=[Here you can insert timestamp of table]
otherwise if you want to drop all your database you can do
$rails db:drop
Run this command:-
rails g migration drop_table_name
then:
rake db:migrate
or if you are using MySql database then:
login with database
show databases;
show tables;
drop table_name;
If you want to delete the table from the schema perform below operation --
rails db:rollback
I was wondering if anyone knew how to update the files (adding/removing/updating an attribute) produced by using the scaffold generator in ruby on rails.
For example:
scaffold student name:string lastname:string
so this will create a the associate files (controller,view,etc) with name and lastname as string attributes. When you db:migrate the project, it'll create the table in the database. However, say I want to update whether it be update it with an addition attribue (ex. studenId:integer) or if its removing or updating an attribute, how do you do that?
I tired just updating the generated files, but when I do that db:migrate it still sets the schema that is generated to what is in the table. Is there a built in script in rails that will update the table?
Any advise appreciated?
Thanks,
D
Full command in this example:
$ rails generate migration add_studentid_to_student
You need new migration file for new attributes, from console:
$ script/gnerate migration add_sudentid_to_sudent
it will generate your_app/db/migrate/8293898391_add_sudentid_to_sudent.rb, spicify in this file your new attributes:
def self.up
add_column :sudents, :studentId, :integer
end
def self.down
remove_column :students, :studentsId
end
after that, back to console:
$ rake db:migrate
and than you can edit your views, model, controller files and use new attribute
Hi Try ruby script/destroy scaffold student and then ruby script/generate scaffold student
also try reading up on rails migrations, for dropping/updating table columns.
http://api.rubyonrails.org/classes/ActiveRecord/Migration.html