我创建了一个Rails应用程序,一切都运行良好。但现在,我想要重命名一个控制器和相关模型:
我想将Corps
控制器更改为Stores
,并将相应的模型也更改为Store
。
在Google上查找,人们建议删除并重新生成控制器和模型。问题是这样会擦除每个文件的实际代码!
有什么解决方案吗?
我创建了一个Rails应用程序,一切都运行良好。但现在,我想要重命名一个控制器和相关模型:
我想将Corps
控制器更改为Stores
,并将相应的模型也更改为Store
。
在Google上查找,人们建议删除并重新生成控制器和模型。问题是这样会擦除每个文件的实际代码!
有什么解决方案吗?
以下是我的做法:
创建一个迁移(migration)以更改表名(数据库层面)。我假设你的旧表名为corps。迁移内容将如下:
class RenameCorpsToStores < ActiveRecord::Migration
def change
rename_table :corps, :stores
end
end
更改您的模型文件名、模型类定义和模型关联:
corp.rb
改为store.rb
store.rb
中的代码:将class Corp
更改为class Store
has_many :corps
改为has_many :stores
更改您的控制器文件名和控制器类定义:
corps_controller.rb
改为stores_controller.rb
stores_controller.rb
中的代码:将class CorpsController
更改为class StoresController
重命名视图文件夹,从corps
改为stores
。
在config/routes.rb
文件中对路径进行必要的更改,例如resources :corps
改为resources :stores
,并确保代码中所有引用都从corps
更改为stores
(如corps_path等)。
记得运行迁移 :)
如果上述不可行,则尝试删除db/schema.rb
并执行:
$ rake db:drop db:create db:migrate
corps
更改为store
。 更重要的是,您应该在config/routes.rb文件中将corps
更改为store
。
因此,您将对控制器、相关模型、视图、辅助程序、测试和路由文件进行更改。
我认为您所看到的使用destroy
和generate
更好一些。 我已经在这里提供了如何操作的答案:Rails:重命名控制器和相应模型
gem install rails_refactor
使用前,请确保cd到您的Rails项目的根目录。
重命名控制器:rails_refactor rename OldController NewController
$ rails_refactor rename DummyController.old_action new_action
$ rails_refactor rename OldModel NewModel
还有一件重要的事情是,您需要更新模型关联。无论您是手动更名还是销毁并生成资源(因为它们存在于其他模型中),都必须这样做。您可以运行迁移以更改数据库中外键列的名称,并更改代码中对这些外键的所有引用:
rename_column :table, :old_id, :new_id
或者在声明使用旧外键的关联时设置自定义外键:
belongs_to :new, foreign_key: "old_id"
单数、减号和大写字母:
grep -rl corp | xargs sed -i 's/corp/store/g'
grep -rl Corp | xargs sed -i 's/Corp/Store/g'
复数、负数和正数(如果复数只需要在末尾添加一个s字符,则将单数替换为复数):
grep -rl corps | xargs sed -i 's/corps/stores/g'
grep -rl Corps | xargs sed -i 's/Corps/Stores/g'
重命名文件:
find . -name '*corp*' -exec bash -c 'mv $0 ${0/corp/store}' {} \;
在一些*nix操作系统中(包括Slackware),有一个叫做rename的实用工具可以帮助你重命名文件:
shopt -s globstar
rename -v corps stores app/**/*corps* config/**/*corps* test/**/*corps*
请注意,检查重命名是否是您所认为的内容。我知道其他发行版(如Ubuntu)可能会使用同名但不同的实用程序(参见https://unix.stackexchange.com/questions/78621/find-rename-command-doesnt-work)。在Ubuntu上,您应该执行以下操作:
shopt -s globstar
rename -v 's/corps/stores/' app/**/*corps* config/**/*corps* test/**/*corps*
如果您有模型测试,您需要进行更改:
文件重命名:corp_test.rb -> store_test.rb(控制器测试、集成测试、固定装置等也是如此)
store_test.rb的代码:将class CorpTest更改为class StoreTest。
并且所有控制器、模型、集成、固定装置测试中的corp引用都需要更改。
如果您要手动更改控制器,则需要在以下位置进行更改:
对于模型,Nobita的答案非常好。
作为一个刚刚完成这个痛苦过程的人,最重要的步骤是构建足够的测试来检查尽可能多的功能。它们不仅应该涵盖您计划重命名的模型/控制器,还应涵盖所有其他模型/控制器/视图部分。无论如何,这都是一个很好的(甚至是必须的)实践。
通过迭代来执行这些步骤,有时候你需要回到几次步骤(5次或更多次)以发现需要更改的其他文件。现在来看看重命名步骤:
db/migrate
文件夹中所有包含 Corps/Corp
的文件(名称和内容)更改为 Stores/Store
尝试运行:
rake db:drop:all
rake db:create
rake db:migrate
更改 db/seeds.rb
文件的内容。
rake db:seed --trace
(在此步骤中,您可能需要更改其他模型/控制器文件)test/fixtures
文件。您可能不仅需要更改 corps.yml 文件,还需要更改其他相关文件(有些文件可能包括 corp_id)。TESTOPTS="--seed=1981"
或任何其他数字)
find -name "oldname_on_singular?*
来获取需要重命名的文件列表。然后我将其复制到 calc 上,在第二列和第三列中分别粘贴两次。在第一列中,我添加了重命名命令,并在最后一列中更改为新名称,类似于:git mv ./spec/views/oldname ./spec/views/new name
。 - Eduardo Santana