この資料は8/18日のIncrements meetupの発表資料です。
#QiitaのRails5アップデート
はじめに
- 7月に入社しました
- Railsは3.2が出た時ぐらいから
- attr_accessibleとかあったな〜程度の意識
無茶振り
yuku 「QiitaをRails5にしたいんだよね」
終わらなかったので現状を話します
Rails5は何が新しいのか
- ActionCable
- Rails API
- ActiveRecord attributes API
- Turbolinks5
- etc...
みたいな話はしません
Rails5ができなくなったこと
- protected_attributesが使えなくなった
- belongs_toがデフォルトではoptionalではなくなった
- Callbackを中断するのに
false
が非推奨に
Qiitaの現状
- attr_accessible, protectedによるMass Assignment対策
- belongs_to optionalを各所で使用している
- callbackはもちろんfalseを返している
- sprockets-railsは2.x
- 自社でforkしてメンテしているライブラリが多数ある
やったこと
attr_accessible, protectedによるMass Assignment対策
みなさんprotected_attributes、使ってますか?
- Rails公式がサポートを打ち切っている
- egrep -rl 'attr_accessible|attr_protected' app/models/ | wc -l
- → 68個の該当モデル
- どう移行するか
気合で移行する
やることは単純
- 既存の実装をテストで網羅し
- attr_*を 取り除き
- controller側をstrong parameterで書き直し
- 不正なparameterを許可していないかテストを加える
shared_examples_for 'unpermitted parameter rejection' do
let(:target_attributes) { params.with_indifferent_access[model.class.name.downcase] }
context 'with unpermitted attributes attributes' do
it 'does not update' do
expect { subject }.not_to change { model.reload.attributes }
end
end
end
現在 進捗 4/68
belongs_toがデフォルトではoptionalではなくなった
config.active_record.belongs_to_required_by_default = false
にすれば良い
が、optionalを全てで許容しているのはあまり健全ではない
- テストカバレッジを上げて
- オプションをtrueにできるようにしていく(進捗なし)
callbackを中断するのにfalse
が使えなくなった
throw(:abort)
を使う
こんな時に紛らわしかった
# https://speakerdeck.com/claudiob/better-callbacks-in-rails-5
class User < ActiveRecord::Base
before_action :set_default_value
private
def set_default_value
self.admin ||= false
end
end
User.create!
# => ActiveRecord::RecordNotSaved
書き換えるのみ
あとは...
- これだけではない
- sprockets-rails3への移行
- 独自メンテナンスしているリポジトリのupstreamへの追従
sprockets-railsのアップデート
- Qiitaはsprocketsを捨てようと作業中
- JSは@mizchiがbrowserify-railsを使った形式に変更。sprocketsはprecompileのみ行う
- CSSは@morishitterが移行中
もう少し捨てられないのでアップデートしていく
node_modulesパッケージをsprocketsとつなぐ
CSSの依存もnode_modulesで管理したい
# Allow stylesheets to import SCSS files from node_modules.
Rails.application.config.assets.paths << Rails.root.join('node_modules')
これだと死んでしまう
sprockets-railsは application
と名のつくものすべてをprecompileしようと頑張る
例えば bootstrap-sass
は application.css.ejs.scss
というファイルを持っている
こいつらをprecompileに含めるわけにはいかないので、以前はapplication.rb
にこう書いていた
config.assets.precompile = [
::Sprockets::Railtie::LOOSE_APP_ASSETS,
'application.css',
'application.js',
'bundle.js',
'components.js',
....
]
これだとできない
sprockets-railsが3.0から config.assets.precompile
へのデフォルト値のセットのタイミングを変えた
なので assets.rb
に移動させることで解決する
forkしてメンテナンスしているリポジトリのupstreamへの追従
forkして自社でメンテナンス、と行っても必要なパッチだけをあてて放置してしまうパターンもおおいのでは
- https://github.com/increments/i18n-js
- https://github.com/increments/compass-core
- https://github.com/increments/wicked_pdf
大体そんな感じになっている
本家にPull Requestを送ったり、Qiita側で対応しながらupstreamに追従できるように変更した
## 最後に
- Railsが示している移行のパスに乗れるように、普段から意識しておく
- forkは用法用量を守って(頼む)