このエントリーをはてなブックマークに追加

2017年1月14日土曜日

Rails5 alias_method_chain is deprecated.

 こんにちは、Hiroです。
 直近のプロジェクトでは、Rails5を使っているのですが、利用しているgem関連で下記のような警告が大量に出力されるので、少し調べてみました。
(「./bin/rails c」や「./bin/bundle exec rspec」を実行すると大量に出力されます。)
DEPRECATION WARNING: alias_method_chain is deprecated.
これは、Rails5からはActiveSupportの「alias_method_chain」がdeprecatedになり、代わりに「Module#prepend」を使うように促しています。


alias_method_chainとは


まず、deprecatedになった「alias_method_chain」ですが、下記のように利用します。
class HelloUser
  def hello
    puts 'Hello'
  end

  def hello_with_world
    hello_without_world
    puts 'World'
  end
  alias_method_chain :hello, :world
end
上記のコードは、「alias_method」を使った場合は、下記と同等になります。
class HelloUser
  def hello
    puts 'Hello'
  end

  def hello_with_world
    hello_without_world
    puts 'World'
  end
  alias_method :hello_without_world, :hello
  alias_method :hello, :hello_with_world
end
helloメソッドがhello_with_worldメソッドに置き換わり、元々のhelloメソッドはhello_without_worldメソッドとして使えるようになります。
実行結果を下記に記載しますが、置き換わっているのがわかると思います。
[1] pry(main)> hello_user = HelloUser.new
[2] pry(main)> hello_user.hello
Hello
World
[3] pry(main)> hello_user.hello_without_world
Hello


Module#prependとは


早速、「Module#prepend」の使い方ですが下記のように使います。
class HelloUser
  def hello
    puts 'Hello'
  end
end

module HelloWithWorld
  def hello
    super
    puts 'World'
  end
end
HelloUser.prepend(HelloWithWorld)
prependされたHelloWithWorldモジュールは継承関係上で、HelloUserクラスより手前に位置することになり、helloメソッドを オーバーライドしたような形になります。
そのため、HelloWithWorldモジュールのメソッド内でsuperを呼び出すことで元々のメソッドを呼び出すことができます。
実行結果とancestorsメソッドで継承関係を表示しておきます。HelloWithWorldがHelloUserの前にあるのがわかると思います。
[1] pry(main)> hello_user = HelloUser.new
[2] pry(main)> hello_user.hello
Hello
World
[3] pry(main)> HelloUser.ancestors
=> [HelloWithWorld,
 HelloUser,
 ActiveSupport::ToJsonWithActiveSupportEncoder,
 Object,
 PP::ObjectMixin,
 RequireAll,
 ActiveSupport::Dependencies::Loadable,
 JSON::Ext::Generator::GeneratorMethods::Object,
 ActiveSupport::Tryable,
 Kernel,
 BasicObject]
モンキーパッチなどを書くときに利用することになると思います。(モンキーパッチなんて書かずに、githubにプルリクする方がよいですが)


とりあえず、DEPRECATION WARNINGの出力をなくしたい


Rails5にしたものの、全てのgemに対して、この警告を消すための書き換えの対応をしていくのは大変。
ただ、この出力が目障りという方は、「config/application.rb」に下記を書けば、消すことができますが、自己責任でお願いしますね。
require_relative 'boot'

require 'rails/all'

# TODO: DEPRECATION WARNING: alias_method_chain is deprecated
ActiveSupport::Deprecation.silenced = true

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
...
...


deprecatedなメソッドは、今後のアップデートで利用できなくなることもありますので、しっかりと理解した上で利用し、可能であれば、置き換えていくようにしましょう。

0 件のコメント:

コメントを投稿