LoginSignup
16

More than 5 years have passed since last update.

RailsでSQLite3使う時はgemのバージョンを指定しないといけない

Last updated at Posted at 2019-02-16

はじめに

Railsを勉強すべくチュートリアルやってみたが、
SQLite3関連でエラーが起きたので調べてみた

環境

  • OS: MacOS Mojave 10.14.3
  • ruby: 2.3.7
  • rails: 5.2.2
  • SQLite3: 3.24.0

再現方法

  • テスト用のアプリを作成し、サーバを起動する
% rails new sqlite3_test  
% cd sqlite3_test && rails server
  • ブラウザからアクセスすると、エラーが発生する rails_error.png

調査してみる

上の方からスタックトレースをみていく

Puma caught this error: Error loading the 'sqlite3' Active Record adapter. Missing a gem it depends on? can't activate sqlite3 (~> 1.3.6), already activated sqlite3-1.4.0. Make sure all dependencies are added to Gemfile. (LoadError)
/Library/Ruby/Gems/2.3.0/gems/bundler-2.0.1/lib/bundler/rubygems_integration.rb:408:in `block (2 levels) in replace_gem'
/Library/Ruby/Gems/2.3.0/gems/activerecord-5.2.2/lib/active_record/connection_adapters/sqlite3_adapter.rb:12:in `<main>'
/Library/Ruby/Gems/2.3.0/gems/bootsnap-1.4.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `require'
/Library/Ruby/Gems/2.3.0/gems/bootsnap-1.4.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `block in require_with_bootsnap_lfi'

最初のメッセージを読むと、sqlite3のgemは1.3.xしか使えないのに、1.4.0を使おうとしているようだ。
(gemのバージョン指定方法はrailsドキュメントを参照)

Missing a gem it depends on? can't activate sqlite3 (~> 1.3.6), already activated sqlite3-1.4.0. Make sure all dependencies are added to Gemfile. (LoadError)

どうやらsqlite3の1.4.0をインストールしてそれを使おうとしているらしい。
gemのバージョンを調べてみる。

% gem list | grep sqlite3
sqlite3 (1.4.0)

Gemfileも確認してみる。

% cat Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.3.7'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.2.2'
# Use sqlite3 as the database for Active Record
gem 'sqlite3'

sqlite3のバージョンを指定していないので、最新版(今は1.4.0)をインストールしているらしい。
ということは、ここを書き換えて1.3.xだけインストールするようにすれば解決するはず。

% vim Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.3.7'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.2.2'
# Use sqlite3 as the database for Active Record
# バージョン番号を'~> 1.3.6'に指定
+ gem 'sqlite3', '~> 1.3.6'

bundle installして、gemを更新し、サーバを起動する。

% bundle install --clean
% rails server

アクセスしてみる
スクリーンショット 2019-02-16 23.26.09.png

動いた

もう少し調べてみる(おまけ)

どうして1.4.0だと弾いてしまうのだろう?
気になったので、ソースコードを追ってもう少し調べてみる

さっきのスタックトレースを上からみていく

  • /Library/Ruby/Gems/2.3.0/gems/bundler-2.0.1/lib/bundler/rubygems_integration.rb:in block (2 levels) in replace_gem
    bundler側なので、多分関係ない

  • /Library/Ruby/Gems/2.3.0/gems/activerecord-5.2.2/lib/active_record/connection_adapters/sqlite3_adapter.rb:12:in <main>'
    ちょっと怪しいのでみてみる

% less /Library/Ruby/Gems/2.3.0/gems/activerecord-5.2.2/lib/active_record/connection_adapters/sqlite3_adapter.rb
# frozen_string_literal: true

require "active_record/connection_adapters/abstract_adapter"
require "active_record/connection_adapters/statement_pool"
require "active_record/connection_adapters/sqlite3/explain_pretty_printer"
require "active_record/connection_adapters/sqlite3/quoting"
require "active_record/connection_adapters/sqlite3/schema_creation"
require "active_record/connection_adapters/sqlite3/schema_definitions"
require "active_record/connection_adapters/sqlite3/schema_dumper"
require "active_record/connection_adapters/sqlite3/schema_statements"

gem "sqlite3", "~> 1.3.6"
require "sqlite3"

gem "sqlite3", "~> 1.3.6" が明らかにおかしい。
これだと1.3.xしか使えないので、1.4.0は当然使えない。

ここを以下の様に書き換えてみると、sqlite3が1.4.0でも動く(動作確認結果は割愛)

% vim /Library/Ruby/Gems/2.3.0/gems/activerecord-5.2.2/lib/active_record/connection_adapters/sqlite3_adapter.rb

# frozen_string_literal: true

require "active_record/connection_adapters/abstract_adapter"
require "active_record/connection_adapters/statement_pool"
require "active_record/connection_adapters/sqlite3/explain_pretty_printer"
require "active_record/connection_adapters/sqlite3/quoting"
require "active_record/connection_adapters/sqlite3/schema_creation"
require "active_record/connection_adapters/sqlite3/schema_definitions"
require "active_record/connection_adapters/sqlite3/schema_dumper"
require "active_record/connection_adapters/sqlite3/schema_statements"

# 下記の書き方をすると、1.xで動作する様になる。
# すごく雑なバージョン指定だけど、動作検証のためこうしている。
gem "sqlite3", "~> 1.3"
require "sqlite3"

結論

実はこちらの記事で大体のところが書いてあった。
https://qiita.com/Kta-M/items/254a1ba141827a989cb7

sqlite3の1.4.0が2/4にリリースされたが、railsの方がまだ対応できておらずこうなっているらしい。
既に修正のためのプルリク↓が承認されているので、もうじき直るとのこと。(じゃあこの記事いらないじゃん…)
https://github.com/rails/rails/commit/6d5f2511e6d9b95a8ac8399c234aa6cd074af51d

PRだとこう直してる

require "active_record/connection_adapters/sqlite3/schema_dumper"
require "active_record/connection_adapters/sqlite3/schema_statements"

- gem "sqlite3", "~> 1.3.6"
+ gem "sqlite3", "~> 1.3", ">= 1.3.6"

これなら、1.xかつ1.3.6以上のバージョンに限定してrequireできる。こっちの方が賢い。

所感

あんまり大した記事じゃないのに長くなってしまった…
でもバグに当たった時にソースみながら調査するって結構大事だな、と思った。(あまりやってないけど)

もっと深い所まで理解できる様になっていきたいな。

参考

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
16