Data migrations for older version of friendly id - ruby-on-rails

I'm migrating a very old app from friendly_id 3.2 to 5.1.
I have a user model which currently has a cached_slug field. I created a new field called just slug. Initially, I thought I could just copy the data over from cached_slug to slug, but I noticed that there's also a whole other table called slugs which looks like this:
create_table "slugs", force: :cascade do |t|
t.string "name", limit: 255
t.integer "sluggable_id"
t.integer "sequence", default: 1, null: false
t.string "sluggable_type", limit: 40
t.string "scope", limit: 255
t.datetime "created_at"
end
Following the directions in the FriendlyID README for the Rails Quickstart, I ran rails generate friendly_id which created this table:
create_table "friendly_id_slugs", force: :cascade do |t|
t.string "slug", null: false
t.integer "sluggable_id", null: false
t.string "sluggable_type", limit: 50
t.string "scope"
t.datetime "created_at"
end
So now I'm all confused about what I need to do to complete migration. I tried creating a new user with the console and the friendly_id_slugs table is still empty, so I'm not sure when or what it's used for.
I have two questions:
1) What is this other table used for
2) What do I need to do to migrate my old slugs to the new table/field so it will continue to work moving forward?
Thanks!

If you don't mind losing the FriendlyId's History records (i.e: the old slugs),
drop the old slug table
in the rails console, run <ModelName>.find_each(&:save) for all friendly_id models.
Step 2 should regenerate new slugs.
Warning: Test before doing this on production servers!
Update: You can also perform step 2 in a migration file
class RegenerateSlugs < ActiveRecord::Migration
def change
# <ModelName>.find_each(&:save)
User.find_each(&:save)
Article.find_each(&:save)
end
end

Related

rails migration generating random tables. Where is this coming from?

When I run rails db:migrate without a new migration it seems to have added two new tables: questions and questions_1.
In my schema file I see:
create_table "questions", id: false, force: :cascade do |t|
t.integer "id"
t.text "text"
t.boolean "active"
t.integer "organization_id"
t.datetime "created_at"
t.datetime "updated_at"
t.bigint "account_id"
t.bigint "team_id"
end
create_table "questions_1", id: false, force: :cascade do |t|
t.integer "id"
t.text "text"
t.boolean "active"
t.integer "organization_id"
t.datetime "created_at"
t.datetime "updated_at"
t.bigint "account_id"
t.bigint "team_id"
end
I don't have any migrations making these tables. I'm guessing this is some sort of convention. Where do I look to fix this? All recent changes are in the app/ directory and a migration I made has been rolled back and then deleted. Yet when I run rails db:migrate I always get these new tables.
Any ideas?
Rails won't create tables with any name other than the ones specified in a migration. If the table already exists then it will throw an error.
I believe someone has run a migration creating the second table on your database, and then deleted the migration. When rails creates your schema.rb file, it uses your database rather than any migrations, meaning this file reflects your actual database state rather than the one your migrations suggest would be the case.
If you're sure you don't want the second table and it has no data in it, then you can write out a new migration to delete this table, run it, and then delete it. This will return your database state to the one your migrations suggest would be the case. You can then run rake db:schema:dump to update your schema.

Rails 5 after ran migration limit is gone in schema

Recently I upgraded my application from Rails 4.2 to Rails 5.0.3. Then I am trying to run a migration:
class AddInvitationToJoinToContests < ActiveRecord::Migration
def change
add_column :goods, :new_field, :string
end
end
The migration ran correctly, but other table fields's limit option are gone:
create_table "users", force: :cascade do |t|
- t.string "name", limit: 191, null: false
- t.string "language", limit: 191
- t.string "image_id", limit: 191
+ t.string "name", null: false
+ t.string "language"
+ t.string "image_id"
end
Any idea why?
Related issue:
Rails 4.2 stops to add limit - rails/rails#19001
This could be because Rails 5 does not list the "limit" for columns if the limit matches the default for that column's data type.
https://github.com/rails/rails/commit/835617b71d2e829c27dbd16a82f22c186c821a0f
You can see in the comments of this changeset that this is to keep the schema.rb database-agnostic. I would suspect that for whichever database adapter you're using, the default 'limit' for string types is 191.

rails_admin using outdated table names

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.

Remove Tables from Schema

This is probably a fairly basic question, but I'm at a loss on how to clean up after installing a gem I decided not to use. During the install process of Attachinary, the install instructions said to run rake attachinary:install:migrations - creating a new table and index in my schema, noted here:
create_table "attachinary_files", force: :cascade do |t|
t.integer "attachinariable_id"
t.string "attachinariable_type"
t.string "scope"
t.string "public_id"
t.string "version"
t.integer "width"
t.integer "height"
t.string "format"
t.string "resource_type"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "attachinary_files", ["attachinariable_type", "attachinariable_id", "scope"], name: "by_scoped_parent", using: :btree
I later decided to go with a simplier attachement gem and I'm attempting to clean up and remove all the "stuff" created during the attachinary install.
Any advice on how to clean up the db? I'm running Postgresql if that makes any difference.
Create a migration:
bundle exec rails g migration remove_attachinary
Then tell Rails what to do:
def up
drop_table :attachinary_files
end
Remove the change method present by default
If ever you'd like this migration to be reversible, copy your previous code in a down method

How to rename fields and make them not nulls

My current schema looks like:
create_table "users", :force => true do |t|
t.string "username"
t.string "firstname"
t.string "lastname"
t.datetime "loggedin_at"
t.datetime "created_at"
t.datetime "updated_at"
t.integer `user_status`
end
I want to rename username to user_name, and make all the fields not null (they are currently nullable).
How would I do this? Do I create a migration file using rails generate, and then have to tweak it manually? How so?
It can help if you specify the Rails version number.
Before 3.0, it is:
Rails: How can I rename a database column in a Ruby on Rails migration?
If it is 3.0 or later, then you can look at the Migration documentation, such as rails generate instead of script/generate.

Resources