How to rename rails controller and model in a project
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.
Solution 1:
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
: Changeclass Corp
forclass 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
: Changeclass CorpsController
forclass 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:
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: Rails : renaming a controlller and corresponding model
Solution 3:
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:
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.