In my schema.rb,
create_table "devices", force: :cascade do |t|
t.string "uuid"
t.bigint "device_return_id"
t.index ["device_return_id"], name: "index_devices_on_device_return_id"
end
create_table "device_returns", force: :cascade do |t|
t.string "code"
t.datetime "returned_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_foreign_key "devices", "device_returns", column: "device_return_id"
How can I use rails g migration to change all the "device_return" to "exchange" ?
I tired rename_table and rename_index. They didn't change t.index["device_return_id']
Thanks
to change the foreign key you can try
rails g migration ChangeForeignKeyForDevices
then your migration should look like this
class ChangeForeignKeyForDevices < ActiveRecord::Migration
def change
rename_column :device_returns, :old_column_name, :new_column_name
end
end
then run your migration
rails db:migrate
http://api.rubyonrails.org/classes/ActiveRecord/Migration.html
rename_column(table_name, column_name, new_column_name): Renames a column but keeps the type and content.
rename_index(table_name, old_name, new_name): Renames an index.
rename_table(old_name, new_name): Renames the table called old_name to new_name.
Related
Description
I'm on Ruby version 2.6.6 and Ruby on Rails version 6.0.3.2.
Models
Book
Author
Associations
A Book belongs to an Author.
An Author has many Books.
Goal
Remove the Author model and add it as a column to a Book (of type string).
What I've Done
I created and ran 3 migrations, in the following order:
AddAuthorToBooks
class AddAuthorToBooks < ActiveRecord::Migration[6.0]
def change
add_column :books, :author, :string
end
end
DropAuthors
class DropAuthors < ActiveRecord::Migration[6.0]
def change
drop_table :authors do |t|
t.string "full_name", null: false
t.timestamps null: false
end
end
end
RemoveAuthorForeignKeyFromBooks
class RemoveAuthorForeignKeyFromBooks < ActiveRecord::Migration[6.0]
def change
remove_foreign_key :books, :authors
end
end
Schema
Unfortunately, I don't have the schema before I ran the migrations. (I tried checking out an older commit, but the schema file stubbornly refuses to change.)
Here is the current version:
ActiveRecord::Schema.define(version: 2020_08_11_125724) do
create_table "books", force: :cascade do |t|
t.string "title"
t.text "description"
t.string "cover_url"
t.decimal "price"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.integer "author_id", null: false
t.string "author"
t.index ["author_id"], name: "index_books_on_author_id"
end
create_table "books_genres", id: false, force: :cascade do |t|
t.integer "book_id", null: false
t.integer "genre_id", null: false
t.index ["book_id", "genre_id"], name: "index_books_genres_on_book_id_and_genre_id"
t.index ["genre_id", "book_id"], name: "index_books_genres_on_genre_id_and_book_id"
end
create_table "genres", force: :cascade do |t|
t.string "name"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "reviews", force: :cascade do |t|
t.string "username"
t.decimal "rating"
t.text "body"
t.integer "book_id", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["book_id"], name: "index_reviews_on_book_id"
end
add_foreign_key "reviews", "books"
end
Problem
The author table has been removed, the add_foreign_key "books", "authors" (I think that's how it went) is gone, too, but the author_id stubbornly remains in the books table.
Furthermore, there's an integer author_id and an index of the same name.
What I'm Planning
I thought of just deleting these 2 columns with another migration, but I don't know if that would...
...fix the issue and erase the old Author model completely,
...and that it's the clean/recommended way of doing things. If needed, I could roll back the migrations and try a better method.
About the unusual `schema.rb` behavior
I tried checking out an older commit, but the schema file stubbornly refuses to change.
This is quite unusual. Do verify that you're tracking the db/schema.rb file using git. If it is tracked, there's no reason why checking out an older commit shouldn't return it to the older state. At that point, you should be able to:
$ rails db:drop
$ rails db:create
$ rails db:schema:load
...to load the old schema into the database. Then, you should be able to return to the latest code with git, and run pending migrations after the date at which the older schema was created.
About a cleaner way to implement this
Before writing the below migration, the first step would be to remove any existing relationship written in the Book class. For example:
# app/models/book.rb
class Book < ApplicationRecord
# The line below should be deleted! Otherwise, it will probably interfere
# with the `book.update!(author: ...)` line in the migration.
belongs_to :author
end
I've taken to writing related migrations in a single file, since they're all related. To me, this looks like:
class MoveAuthorToBooks < ActiveRecord::Migration[6.0]
class Author < ApplicationRecord
end
class Book < ApplicationRecord
end
def up
# Start by adding a string column.
add_column :books, :author, :string
# Let's preserve existing author names.
Book.all.each do |book|
author = Author.find(book.author_id)
book.update!(author: author.name)
end
# Now that the names have been moved to the books table, we don't
# need the relationship to `authors` table anymore. This should
# also delete any related foreign keys - manual foreign key deletion
# should not be required.
remove_column :books, :author_id
# Alternative: If you'd created the `authors_id` column using the
# `add_reference` command, then it's probably best to use the opposite
# `remove_reference` command.
#
#remove_reference :books, :author, index: true, foreign_key: true
# Finally, remove the `authors` table.
drop_table :authors
end
def down
# This can be technically be reversed, but that'll need some more code that
# reverses the action of the `up` function, and it may not be needed.
raise ActiveRecord::IrreversibleMigration
end
end
class CreateMessages < ActiveRecord::Migration[5.2]
def change
create_table :messages do |t|
t.text :body
t.integer :user_id
t.timestamps
end
end
end
After running rails db:migrate my schema looks like this...
ActiveRecord::Schema.define(version: 2020_03_20_063104) do
create_table "messages", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "username"
t.string "password_digest"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
I am wondering where the t.text "body" is and where the t.integer "user_id"is and why it isn't showing up in my schema under messages table.
I have checked migration status and all migrations have been ran.
If you ran something like this in your migration file
class CreateMessages < ActiveRecord::Migration[5.2]
def change
create_table :messages do |t|
t.timestamps
end
end
end
Messages table is created and after this you can't create another migration with create_table :messages. Like #Marek Lipka wrote on comments. Either you need to rollback your CreateMessages migration and chance file and run your migration again. Or you need to write another migration to change existing table like this.
class AddBodyAndUserIdToMessages < ActiveRecord::Migration[5.2]
def change
add_column :messages, :body, :text
add_column :messages, :user_id, :integer
end
end
I read a lot about it but i still can't get rid of one table that I have in my db:
create_table "votes", force: true do |t|
t.integer "votable_id"
t.string "votable_type"
t.integer "voter_id"
t.string "voter_type"
t.boolean "vote_flag"
t.string "vote_scope"
t.integer "vote_weight"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "votes", ["votable_id", "votable_type", "vote_scope"],
name: "index_votes_on_votable_id_and_votable_type_and_vote_scope"
add_index "votes", ["voter_id", "voter_type", "vote_scope"],
name: "index_votes_on_voter_id_and_voter_type_and_vote_scope"
I don't have a migration that create this table. But I think this table comes from a previous installation of the acts_as_votable gem. But I might have deleted this migration manually...
I tried to drop_table as follows, but it's not working. Even if I have this migration file, the votes table is still there:
class DropVotesTable < ActiveRecord::Migration
def up
drop_table :votes
end
def down
raise ActiveRecord::IrreversibleMigration
end
end
What should I do to delete this table from my schema.rb file?
EDIT: solution
Even after running the migration the table was still in my schema.rb so I used the rails console:
rails c
ActiveRecord::Migration.drop_table(:votes)
rake db:migrate
And this table finally disappeared.
A very similar question was already asked, bud I can't solve the problem anyway. I am trying to create a new record in rails console and I get this error:
2.1.2 :001 > subject = Subject.new
Mysql2::Error: Table 'simple_cms_development.subjects' doesn't exist: SHOW FULL FIELDS FROM `subjects`
ActiveRecord::StatementInvalid: Mysql2::Error: Table 'simple_cms_development.subjects' doesn't exist: SHOW FULL FIELDS FROM `subjects`
Can somebody please very specifically tell my what should I do?
Here's subject.rb:
class Subject < ActiveRecord::Base
end
and schema.rb:
ActiveRecord::Schema.define(version: 20140617074943) do
create_table "admin_users", force: true do |t|
t.string "first_name", limit: 25
t.string "last_name", limit: 50
t.string "email", default: "", null: false
t.string "username", limit: 25
t.string "password", limit: 40
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "pages", force: true do |t|
t.integer "subject_id"
t.string "name"
t.string "permalink"
t.integer "position"
t.boolean "visible", default: false
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "pages", ["permalink"], name: "index_pages_on_permalink", using: :btree
add_index "pages", ["subject_id"], name: "index_pages_on_subject_id", using: :btree
create_table "sections", force: true do |t|
t.integer "page_id"
t.string "name"
t.integer "position"
t.boolean "visible", default: false
t.string "content_tipe"
t.text "content"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "sections", ["page_id"], name: "index_sections_on_page_id", using: :btree
end
create_subjects.rb:
class CreateSubjects < ActiveRecord::Migration
def up
create_table :subjects do |t|
t.string "name"
t.integer "position"
t.boolean "visible" :default => false
t.timestamps
end
end
def down
drop_table :subjects
end
end
Add a comma in
t.boolean "visible" :default => false`
as in
t.boolean "visible", :default => false`
and then run rake db:migrate
Making sure that config/database.yml file has a valid entry for a database connection on your machine. Look at the development stanza.
More on migrations at guides.rubyonrails.org/migrations.html
More on configuring a database and the database.yml file at
http://edgeguides.rubyonrails.org/configuring.html#configuring-a-database
You need to create a subjects table that defines the attributes you want to persist in the Subject instances.
So say you want title and description. Use this command to create the migration:
rails generate migration subjects title:string description:text
And then run the command
rake db:migrate
Then try your Subject.new command
Alternatively, if you do not want to persist any subject attributes, change the subject class definition to:
class Subject
end
I use the rails_best_practises gem and it came back to me with this alert:
/../db/schema.rb:65 - always add db index (comments => [user_id])
So in db/schema.rb, the line 65 shows the schema of the comments table.
create_table "comments", force: true do |t|
t.string "commenter"
t.text "body"
t.integer "post_id"
t.string "email"
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
end
So what it asks for is to add an index (something) like the one below?
add_index "comments", ["user_id"], name: "index_comments_on_user_id", using: :btree
If so, when I create a new rails migration to accomplish this, will the migration be like that?
def change
add_index :comments, :user_id
end
From the Guides
If you'd like to add an index on the new column, you can do that as
well
So,You should do this to generate a migration file of adding an index.
rails generate migration AddIndexToComments user_id:integer:index
This will produce a migration file like this
class AddIndexToComments < ActiveRecord::Migration
def change
add_index :comments, :user_id
end
end