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
Related
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
One of my migration file vanished to blue sky 🤷♂️ I'm gonna need to rewrite it manually I guess. 😰
This is what I have in schema.rb for that table
+ create_table "collections", force: :cascade do |t|
+ t.string "title"
+ t.string "description"
+ t.bigint "designer_id"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["designer_id"], name: "index_collections_on_designer_id"
+ end
so should my custom migration be as seen below?
def change
create_table :collections do |t|
t.string :title
t.string :description
t.integer :designer_id
t.timestamps
end
end
Should I do anything about add_index?
Thank you!
-----------
EDITED SOLUTION IDEA
Instead of creating new file, I'm going to add to an existing migration file. So that code below should do the job, right?
class AddSlugToCollections < ActiveRecord::Migration[5.1]
def change
create_table :collections do |t|
t.string :title
t.string :description
t.integer :designer_id
t.timestamps
end
add_index :collections, :designer_id
add_column :collections, :slug, :string
add_index :collections, :slug
end
end
Yes, If you want to retain same changes again then you should add index too.
change migration as,
def change
create_table :collections do |t|
t.string :title
t.string :description
t.integer :designer_id
t.timestamps
end
add_index :collections, :designer_id
end
#ganesh Navale is correct. I want to add one more point in this. If your migration is already run then rename the new migration timestamp with the old migration timestamp. You can get old migration timestamp from rake db:migrate:status command.
I have two models connected with a has_and_belongs_to_many association: courses and semesters. rails_admin was only giving me the option to add semesters when creating a course, and not the other way around (and really, it's much more useful to add courses when creating a semester). I made some tweaks the migration:
def change
create_table "courses", force: :cascade do |t|
t.string "department"
t.integer "number"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "semesters", force: :cascade do |t|
t.integer "year"
t.string "season"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "semesters_courses", id: false, force: :cascade do |t|
t.integer "semester_id"
t.integer "course_id"
end
add_index "semesters_courses", ["course_id"], name: "index_semesters_courses_on_course_id"
add_index "semesters_courses", ["semester_id"], name: "index_semesters_courses_on_semester_id"
end
I renamed the intermediary table to semesters_courses from courses_semesters, just for clarity. Not only did this not solve the problem, but now when I try to add a new course, it 500s and tells me:
Could not find table 'courses_semesters'
I know I could make this go away by changing the name back, but I'm not sure where railsadmin is getting that name from (and suspect this to be the source of my problem). I've removed and reinstalled railsadmin, dropped and rewritten the tables, and cleared my browser's cache. When I search my entire project tree for "courses_semesters," I only get results in my error log.
New at Rails dev, so I assume I'm missing some config file somewhere that I need to update, but would love some help on where to find it.
You’re overwriting the join table name.
Option 1 you MUST specify the name of the join table in your models
app/models/course.rb
has_and_belongs_to_many :semesters, join_table: "semesters_courses"
app/models/semester.rb
has_and_belongs_to_many :courses, join_table: "semesters_courses"
Or Option 2 just rename your join table to "courses_semesters" by using migration.
rails g migration rename_courses_semesters
class RenameCoursesSemesters < ActiveRecord::Migration
def self.up
rename_table :semesters_courses, :courses_semesters
end
def self.down
rename_table :courses_semesters, :semesters_courses
end
end
Hope this answers your question.
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.
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.