How to rename rails controller and model in a project

Ruby on-RailsModelControllerRename

Ruby on-Rails Problem Overview


I started a Rails app and everything works fine. But now, I would like to rename a controller and the associated model:

I wanted to change the Corps controller to Stores and the same (without final s) for the model.

Looking on google, people suggested to destroy and then generate again the controller and model. The problem is that it will erase the actual code of each files!

Any solution? Thanks in advance.

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

Here is what I would do:

Create a migration to change the table name (database level). I assume your old table is called corps. The migration content will be:

class RenameCorpsToStores < ActiveRecord::Migration
  def change
    rename_table :corps, :stores
  end
end

Change your model file name, your model class definition and the model associations:

  • File rename: corp.rb -> store.rb
  • Code of store.rb: Change class Corp for class Store
  • Rename all the model associations like has_many :corps -> has_many :stores

Change your controller file name and your controller class definition:

  • File rename: corps_controller.rb -> stores_controller.rb
  • Code of stores_controller.rb: Change class CorpsController for class StoresController

Rename views folders. From corps to stores.

Make the necessary changes in paths in the config/routes.rb file, like resources :corps -> resources :stores, and make sure all the references in the code change from corps to stores (corps_path, ...)

Remember to run the migration :)

If previous is not possible, try to delete the db/schema.rb and execute:

 $ rake db:drop db:create db:migrate

Solution 2 - Ruby on-Rails

In addition to Nobita answer you similarly need to change the test & helper class definitions & file names for corps to store. More Importantly you should change corps to store in your config/routes.rb file

So in total you're making changes to the Controller, associated Model, Views, Helpers, Tests and Routes files.

I think what you’ve seen suggested with destroy & generate is a better option. I’ve given an answer how to do this here: https://stackoverflow.com/questions/5672640/rails-renaming-a-controlller-and-corresponding-model

Solution 3 - Ruby on-Rails

You can try the Rails Refactor gem too, a Command line tool for simple refactors like rename model and controller for Rails projects

Usage:

> Basic renames and refactorings for rails projects. Although these are > not perfect, they'll do a lot of the work for you and save you time. > > Before using, recommend that you start from a clean repository state > so you can easily review changes. > > To install:
gem install rails_refactor > > Before use, make sure you cd to the root of your rails project. > > To rename a controller:
rails_refactor rename OldController NewController > > * renames controller file & class name in file > * renames controller spec file & class name in file > * renames view directory > * renames helper file & module name in file > * updates routes > > To rename a controller action:
$ rails_refactor rename DummyController.old_action new_action > > * renames controller action in controller class file > * renames view files for all formats > > To rename a model:
$ rails_refactor rename OldModel NewModel > > * renames model file & class name in file > * renames spec file & class name in file > * renames migration & class name & table names in file > > ...

Solution 4 - Ruby on-Rails

I addition to Nobita's answer (which I would comment on if I had enough rep), if you're feeling brave then the changes to filenames and references to the model in your code can be automated somewhat. For instance, to change references in your code you can use

Singular, minus and mayus:

grep -rl corp | xargs sed -i 's/corp/store/g'
grep -rl Corp | xargs sed -i 's/Corp/Store/g'

Plural, minus and mayus (singular replace the plural if plural only needs and s character at the end):

grep -rl corps | xargs sed -i 's/corps/stores/g'
grep -rl Corps | xargs sed -i 's/Corps/Stores/g'

Rename files:

find . -name '*corp*' -exec bash -c 'mv $0 ${0/corp/store}' {} \;

And there is a utility called rename on some *nix flavours (including Slackware) which will help you rename the files:

shopt -s globstar
rename -v corps stores app/**/*corps* config/**/*corps* test/**/*corps*

Check rename is what you think it is though, I've known other distributions like Ubuntu to ship with a different utility of the same name (see https://unix.stackexchange.com/questions/78621/find-rename-command-doesnt-work). On Ubuntu you would do this instead:

shopt -s globstar
rename -v 's/corps/stores/' app/**/*corps* config/**/*corps* test/**/*corps*

Note that you want to avoid renaming any files in db/ except possibly in your seeds.rb file, so you probably want to exclude this directory and make any changes manually.

Solution 5 - Ruby on-Rails

One other important thing is that you need to update the model associations, which you'll have to do whether you rename manually or destroy and generate the resource (since they exist in the other models). You can either run a migration to change the column names of the foreign keys in the database and change all references to those foreign keys in the code:

rename_column :table, :old_id, :new_id

or set a custom foreign key when declaring the association that uses the old foreign key:

belongs_to :new, foreign_key: "old_id"

Also if your resource includes images, they are often stored in a directory that includes the resource name but (with carrierwave at least) once the resource's name is changed they'll be referenced incorrectly (file exists at '/uploads/old/image/1/pic.jpg' but is looked for at 'uploads/new/...'), so you'll have to either delete and re-upload the images, move them to the new path, or perhaps change where they're being looked for.

Solution 6 - Ruby on-Rails

And if you have model tests, you need to change:

File rename: corp_test.rb -> store_test.rb (also for controller tests, integration tests, fixture, etc.)

Code of store_test.rb: Change class CorpTest for class StoreTest.

And all the references of corp in the controller, model, integration, fixture tests.

Solution 7 - Ruby on-Rails

As someone that just finish this painful process the MOST important step is to build enough TESTS to check as much functionality as possible. They should cover not only the model/controller that you plan to rename but also all other models/controllers/views parts. Anyhow it's a good (or maybe even a must) practice.

Do this steps by iterations, sometimes you need to comeback to steps few times (5 and more) to discover additional files that need to be changed. And now for the rename steps:

  1. Change all the files (name and content) the include Corps/Corp to Stores/Store in db/migrate folder

  2. Try to run:

    rake db:drop:all

    rake db:create

    rake db:migrate

  3. Change content of db/seeds.rb file.

  4. Try to run: rake db:seed --trace (In this step you may need to change some other model/controller files.)

  5. Change test/fixtures files. you may need to change not only corps.yml but other related files (some files may include corp_id).

  6. Try to run your tests, it's better to run it with fixed seed (add: TESTOPTS="--seed=1981" or any other number)

  7. Rename to files (name and content) be carefull sometimes you need to change test and other app file

Solution 8 - Ruby on-Rails

for controller you will have to make change in following places if you're doing it manually:

  • route
  • app/views
  • app/controllers
  • test/controllers
  • app/helper
  • app/assets/javascripts/
  • app/assets/stylesheets/

for model, Nobita's answer is pretty good

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionhtaidirtView Question on Stackoverflow
Solution 1 - Ruby on-RailsNobitaView Answer on Stackoverflow
Solution 2 - Ruby on-RailsHollyView Answer on Stackoverflow
Solution 3 - Ruby on-RailsAsme JustView Answer on Stackoverflow
Solution 4 - Ruby on-RailsDanView Answer on Stackoverflow
Solution 5 - Ruby on-RailsPwnrarView Answer on Stackoverflow
Solution 6 - Ruby on-RailsBenjamin J. BenoudisView Answer on Stackoverflow
Solution 7 - Ruby on-RailsChaosPredictorView Answer on Stackoverflow
Solution 8 - Ruby on-RailsRaviView Answer on Stackoverflow