182
183

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Rails4へのアップデート時に引っかかったポイントいくつか

Last updated at Posted at 2013-07-08

Rails 4.0.0がリリースされたので今参加しているプロジェクトのアプリのアップデートが出来るかを試してみました。

やってみた結果としては、2.3 -> 3.0や、3.0 -> 3.1に比べると大分楽にバージョンアップできる感じです。

たまたま今のプロジェクトで引っかかった問題について、メモがてらまとめておきます。

rake rails:update

diffを見ながらconfigファイルを書き換える。
そんなに大きな変更は無い。
rails4からはinitializerに色々移せって感じで、application.rbが軽量化されてるけど、元のままでも別に問題無い。
設定項目の重複だけ注意。

strong_parameters

元々、gemで先行導入して取り入れていたので概ね問題無く移行できました。

attr_accesibleを利用したセキュリティ対策は、外部のgemに分離されているため、
config.active_record.whitelist_attributes = falseが残っていると警告されます。
attr_accesibleを使いたい場合は、protected_attributesというgemで対応できますが、素直にstrong_parametersに移行する方が良いんじゃないでしょうか。

気を付けておきたいのはdeviseです。
deviseのカスタムコントローラー等を利用していると、strong_parametersの対応を忘れてしまって、いきなりログインできなくなったり、ユーザー登録出来なくなったりします。
というか私は、いきなりテストが落ちてしばらく悩みましたw

後、rails_adminはとりあえず大丈夫でした。

ActiveRecordの関連の記述方法

has_many等の関連は、conditionsというオプションでベースとなるレコードの情報を利用して条件指定を追加できる機能がありましたが、deprecatedになっています。

こんな感じで書けって事らしい。

# before
has_many :comments, conditions: ->(record) { ["comments.writer_id = ?", record.owner_id] }

# after
has_many :comments, ->(record) { where(writer_id: record.owner_id) }

ActiveRecordのfinderメソッドとSunspot

SunspotというSolrから検索した結果とActiveRecordを連携させるgemを利用しています。
Rails4で動作こそしますが、内部でscopedを利用しているため、deprecatedがガンガン出ます。
Rails4からはallを使うのが正しいですね。

現時点(2013/7/8)でpull requestは既に上がっていますが、まだマージされていないので、ちゃんと直るのはもうちょっと先じゃないかな。
わざわざフォークするのも面倒だし、様子見中です。

ActiveRecordのincludesで読み込んだ関連の値を利用するためのreferencesメソッド

今まで以下のような感じでincludesでeager loadingした関連レコードの値をメソッドチェインで利用して、検索条件に含める事ができました。

Comment.includes(:post).where("posts.published = ?", true)

4.0.0ではこの記述はdeprecatedとなり、includesで読み込んだレコードの値を利用したい時は明示的にreferencesを呼ぶようになりました。

Comment.includes(:post).where("posts.published = ?", true).references(:posts)

以前のままだとSQLのパーサー書くのが大変になるかららしいです。
ちょっと面倒な気がする。

これの影響で、Sunspotでまたdeprecatedが出ます。

## find_by_xxxメソッド無くなった (ぐあっと書いたら嘘書いてたので修正)
これは、一切使ってなかったので問題無し。

find_all_by_xxxとかがdeprecatedになった。

これは、一切使ってなかったので問題無し。
find_byを使うようにする。

rspecでトランザクションが上手く動かない

rspecとdatabase_cleanerを利用しているのですが、トランザクションのロールバックを期待して記述していたテストケースが急に落ちるようになりました。
どうもfixtureの読み込み処理が修正されたのが原因らしいです。

rspec v2.14
database_cleaner githubのmaster
を利用していますが、詳細まで追っかけてないので詳しくは不明です。
どなたかご存知でしたら解決策を教えてください…。

追記 (2013/7/9)
@yuki24 さんのコメントを受けて、再現するテストケースとログを用意してみました。
データベースはmysql2です。

v4.0.0: https://github.com/joker1007/transaction_test
v3.2.13: https://github.com/joker1007/transaction_test3

4.0.0 のtest.log

[1m[36mActiveRecord::SchemaMigration Load (0.2ms)[0m [1mSELECT `schema_migrations`.* FROM `schema_migrations`[0m
  [1m[35m (0.2ms)[0m SELECT @@FOREIGN_KEY_CHECKS
  [1m[36m (0.1ms)[0m [1mSET FOREIGN_KEY_CHECKS = 0[0m
  [1m[35m (0.1ms)[0m SELECT DATABASE() as db
  [1m[36m (0.3ms)[0m [1mselect table_name from information_schema.views where table_schema = 'transaction_test_test'[0m
  [1m[35m (5.2ms)[0m TRUNCATE TABLE `posts`;
  [1m[36m (0.1ms)[0m [1mSET FOREIGN_KEY_CHECKS = 1[0m
  [1m[35m (0.1ms)[0m BEGIN
  [1m[36m (0.1ms)[0m [1mCOMMIT[0m
  [1m[35m (0.0ms)[0m BEGIN
  [1m[36m (0.2ms)[0m [1mSELECT COUNT(*) FROM `posts`[0m
  [1m[35mSQL (0.2ms)[0m INSERT INTO `posts` (`created_at`, `title`, `updated_at`) VALUES ('2013-07-09 05:08:29', 'title0', '2013-07-09 05:08:29')
  [1m[36mSQL (0.1ms)[0m [1mINSERT INTO `posts` (`created_at`, `title`, `updated_at`) VALUES ('2013-07-09 05:08:29', 'title1', '2013-07-09 05:08:29')[0m
  [1m[35mSQL (0.1ms)[0m INSERT INTO `posts` (`created_at`, `title`, `updated_at`) VALUES ('2013-07-09 05:08:29', 'title2', '2013-07-09 05:08:29')
  [1m[36m (0.1ms)[0m [1mSELECT COUNT(*) FROM `posts`[0m
  [1m[35m (0.8ms)[0m ROLLBACK

3.2.13 のtest.log

Connecting to database specified by database.yml
  [1m[36m (0.1ms)[0m [1mSELECT @@FOREIGN_KEY_CHECKS[0m
  [1m[35m (0.1ms)[0m SET FOREIGN_KEY_CHECKS = 0
  [1m[36m (0.1ms)[0m [1mSELECT DATABASE() as db[0m
  [1m[35m (0.2ms)[0m select table_name from information_schema.views where table_schema = 'transaction_test3_test'
  [1m[36m (5.7ms)[0m [1mTRUNCATE TABLE `posts`;[0m
  [1m[35m (0.1ms)[0m SET FOREIGN_KEY_CHECKS = 1
  [1m[36m (0.1ms)[0m [1mBEGIN[0m
  [1m[35m (0.1ms)[0m SAVEPOINT active_record_1
  [1m[36m (0.1ms)[0m [1mRELEASE SAVEPOINT active_record_1[0m
  [1m[35m (0.0ms)[0m BEGIN
  [1m[36m (0.1ms)[0m [1mSELECT COUNT(*) FROM `posts` [0m
  [1m[35m (0.1ms)[0m SAVEPOINT active_record_2
  [1m[36mSQL (0.1ms)[0m [1mINSERT INTO `posts` (`created_at`, `title`, `updated_at`) VALUES ('2013-07-09 05:07:08', 'title0', '2013-07-09 05:07:08')[0m
  [1m[35mSQL (0.2ms)[0m INSERT INTO `posts` (`created_at`, `title`, `updated_at`) VALUES ('2013-07-09 05:07:08', 'title1', '2013-07-09 05:07:08')
  [1m[36mSQL (0.1ms)[0m [1mINSERT INTO `posts` (`created_at`, `title`, `updated_at`) VALUES ('2013-07-09 05:07:08', 'title2', '2013-07-09 05:07:08')[0m
  [1m[35m (0.1ms)[0m ROLLBACK TO SAVEPOINT active_record_2
  [1m[36m (0.1ms)[0m [1mSELECT COUNT(*) FROM `posts` [0m
  [1m[35m (0.7ms)[0m ROLLBACK
  [1m[36m (0.1ms)[0m [1mROLLBACK[0m

色々試してみた所、DatabaseCleaner.strategy:truncationだと4.0.0でも正常に終了するようです。
:trunsaction時はsavepointを利用する事でARのtransactionを実現していた部分が、4.0.0で呼ばれなくなってる事が、期待通りの結果にならない理由のようです。

引っかかった点といえば、こんな所です。

182
183
10

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
182
183

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?