rails - rails4 升级到rails8 的过程
访问量: 39
2019年有几个项目,用的是rails4, ruby 2.5, ruby 2.6 。现在统一给他们做个升级。
1. 找个最新的docker 环境, ruby 3.3.10
2. 删掉原来的Gemfile中的gem 版本号。 也可以删掉Gemfile.lock
3. gem redis 与 redis-rails是冲突的,删掉 redis-rails
4. application.yml中,不要使用 << default 这样的用法了。psych最新版本不支持了。https://stackoverflow.com/a/78987406/445908
config/database.yml , application.yml , log4r.yml 都检查下。
5. 创建 app/assets/config/manifest.js, 内容为:
//= link_tree ../images //= link_directory ../javascripts .js //= link_directory ../javascripts .coffee //= link_directory ../stylesheets .css //= link_directory ../stylesheets .scss
6. config/application.rb ,删掉:
config.active_record.raise_in_transactional_callbacks = true
7. 修改 config/routes.rb 路由,不要在路由中使用 : 或者 => 这样的语法,例如
### 修改的内容:
1. 1.
挂载Ckeditor引擎 :
- 旧语法: mount Ckeditor::Engine => '/ckeditor'
- 新语法: mount Ckeditor::Engine, at: '/ckeditor'
2. 2.
POST路由定义 :
- 旧语法: post "/send_manager_sms_token" => 'api#send_manager_sms_token'
- 新语法: post "/send_manager_sms_token", to: 'api#send_manager_sms_token'
3. 3.
GET路由定义 :
- 旧语法: get '/signout' => 'sessions#destroy', :as => :signout
- 新语法: get '/signout', to: 'sessions#destroy', as: :signout
4. 4.
其他GET路由定义 :
- 旧语法:
```
get "/help_center/:type/articles/:id"
=> 'private/help_articles#show'
get "/help_center/:type/article_list/
:id" => 'private/
help_articles#article_list'
get "/documents/:type/:id" => 'private/
copywritings#show'
```
- 新语法:
```
get "/help_center/:type/articles/:id",
to: 'private/help_articles#show'
get "/help_center/:type/article_list/
:id", to: 'private/
help_articles#article_list'
get "/documents/:type/:id", to:
'private/copywritings#show
```
具体见帮助吧。我是用ai直接修改的。
8.0 删除log4r. 这个特别特别特别重要。否则会引起一切的rails 8 不显示 view层级的错误。
(1. 删除 config/application.rb 中的相关配置。 2. 删除gemfile中的定义。 3. 删除对应的配置文件或者 patch)
8. 遇到了一个500 错误,server error, 但是没有任何信息。 rails c 正常。log 也没有新文件,总之就是看不到问题。
解决办法:RAILS_ENV=production bundle exec rake assets:precompile
进入到生产模式看看。 ( 也可以参考:https://stackoverflow.com/ questions/8772425/500-internal-server-error-for-rails-app-with-no-errors-recorded-in-any-log-file )
9. before_filter => before_action
10. 设置 config/storage.yml
local:
service: Disk
root: <%= Rails.root.join("storage") %>
11. bin/rails credentials:edit 重新生成 credentials.yml
12. 先把 RAILS_ENV=production bundle exec rake assets:precompile 的问题都搞定。例如:
application.coffee 中,一定是包含了.coffee文件的, .js 文件,会报错。
去掉 gem uglifier, 以及 config/environtments/production.rb 中的 uglifier 相关内容,替换为:
# 在Gemfile中添加
gem 'terser'
# 在production.rb中配置
config.assets.js_compressor = :terser
13. 如果仍然遇到500问题,没有任何报警日志,那么就一点一点的分析。例如,去掉 view, 去掉action的逻辑,render text .. 看看怎么样。
_theme.scss.erb
14. 下面也是500问题。 原因应该是rails8 的参数安全机制。
<%= link_to lang[:name], params.merge(lang: lang[:code]) %>
需要修改为:
<%= link_to lang[:name], { controller: 'private/members', action: params[:action], lang: lang[:code]} %>
发现了,我所有的页面,view的错误,都不会显示stack trace ,
其他人也有这样的问题:
1. https://www.ruby-forum.com/t/problem-setting-log-level/223135 它说是rails路径有空格引起的。可是我的没有啊。
发现问题所在了。log4r的问题。跟rails8 不兼容。 干掉它就好了。

15. belongs_to 在rails8 中都强制要求存在了。所以 对于老版本的belongs_to , 在rails8 中要加上 optional: true
belongs_to :member .... ,optional:true
16.
17. link_to 现在会检查是否是允许的参数,例如:
link_to lang[:name], params.merge(lang: lang[:code])
会报错。原因是 lang 没有在params的允许范围内。
解决办法:要么显示指定参数,要么就不要用 params.merge.
link_to lang[:name], request.full_path+"?lang=zh"
18. enum 的格式发生了变化. 现在不再使用 => , 而是使用 ,
rails4: enum my_type: { a: 1, b: 2}
rails8: enum :my_type, {a: 1, b: 2}