Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

【Rails 5.1】あまり知られていない便利な新機能まとめ

先週開催された「RailsConf 2017」にて、Rails 5.1が正式リリースされました。

リリースのお知らせをチェックされた方なら、目玉機能はすでにご存じでしょう。モダンJavaScript(YarnやWebpack)との統合強化、暗号化されたsecrets、システムテストの導入などが挙げられます。そして個人的なお気に入りは、form_forform_tagというやや紛らわしい2つのメソッドがついに統合され、新しいform_withに置き換えられたことです。早く試してみたいところです。

しかし、私がRailsを愛している理由は、こうした大きな新機能ではありません。日々積み重ねられる小さな改善こそが魅力だからです。そうした「開発体験の質を上げる変更」があるからこそ、Railsアプリを書くのが楽しくなるのです。そしてRails 5.1には、まさにそのような改善がたくさん詰まっています。

より一貫性のあるタグヘルパー

Railsのタグヘルパーであるtagcontent_tagを使ったことはありますか?

<%= content_tag :p, @user.name, class: "name" %>

Rails 5.1では、新しいタグヘルパーの記法が追加されました。

tag.divtag.brのように呼び出せるようになり、引数の順序を気にしたり、2つの異なるメソッドを使い分けたりする必要がなくなりました。

<%= tag.p @user.name, class: "name" %>
<%= tag.br %>

この新しいタグヘルパーはデフォルトでHTML5に対応しており、独自のカスタム要素を作ることさえできます。

<%= tag.pea @user.name, class: "name" %>
<!-- <pea class="name">Justin Weiss</pea> に変換される -->

差分以外の変化もアサートできる

私はassert_differenceが大好きです。assert_differenceが登場する前は、テスト内でローカル変数をあれこれ操作して、多くの時間を浪費していました。

old_score = @user.score
@user.answer_question!(...)
assert_equal old_score + 10, @user.score

assert_differenceを使えば、何を検証したいのかがずっと明確になります。

assert_difference "@user.score", 10 do
  @user.answer_question!(...)
end

Rails 5.1では、これをさらに一歩進めたassert_changesが登場しました。

assert_differenceは数値(件数)の変化しかチェックできません。しかしassert_changesなら、文字列から別の文字列への変化や、nilから値への変化といった、数値以外の変化も検証できます。

assert_changes "users(:justin).name", from: "Justin", to: "Bob" do
  @user.update_attributes(name: "Bob")
end

文字列の代わりにラムダ(Proc)を渡すことも可能です。

assert_changes -> { users(:justin).name }, from: "Justin", to: "Bob" do
  @user.update_attributes(name: "Bob")
end

to:オプションには、===で比較できるものであれば何でも指定できます。値の具体的な内容はわからなくても、「何らかの変化が起きる」ということがわかっている場合に非常に便利です。

assert_changes -> { users(:justin).updated_at }, to: ActiveSupport::TimeWithZone do
  @user.update_attributes(name: "Bob")
end

すべてを委譲する

Railsのコードを見ていると、delegateメソッドを目にすることがあります。継承を使わずに、別のクラスの振る舞いを上乗せしたい場合に、委譲(delegation)はとても役立ちます。

class Player
  delegate :id, :name, to: :@user

  def initialize(user)
    @user = user
  end

  def points
    Game.points_for_user(user.id)
  end
end

しかし場合によっては、ラップしているクラスにすべてのメソッド呼び出しを転送したいこともあるでしょう。

Ruby単体でも、method_missingSimpleDelegatorを使えば実現できます。しかしdelegateメソッドとより整合性のある形として、Rails 5.1にはdelegate_missing_toが追加されました。その名の通りの動作をしてくれます。

class Player
  delegate_missing_to :@user

  def initialize(user)
    @user = user
  end

  def points
    Game.points_for_user(user.id)
  end
end

これで、Playerクラスに定義されていないメソッドへの呼び出しは、すべて@user側で探索されるようになります。

おまけ:alias_method_chainがついに廃止!

Ruby 2の私のお気に入り機能のひとつが、Module#prependです。あまりに気に入ったので、記事まで書いてしまったほどです。具体的には、Module#prependがいずれalias_method_chainを置き換えてくれることを願う、という内容でした。

そしてRails 5.1から、alias_method_chainは正式に廃止され、prependへと置き換えられました。

新しいバージョンのRailsは、いつもワクワクさせてくれます。しかし、Railsの美しさを支えているのは、こうした細部です。毎日書くコードをより快適にしてくれる、小さな変更の数々なのです。

そんな変更をどうやって見つければいいのでしょう?答えはchangelogを読み込むこと。興味深いプルリクエストを眺めること。そして、Rails 5.1の小さな新機能の中から、自分の開発ライフを少しでも楽にしてくれるものを見つけることです。

もし面白い機能を見つけたら、ひとりで秘蔵しないでください。ぜひシェアしてみましょう。みんなで新しいことを学べるはずです!

  1. iPhoneの名前を変更する方法|設定アプリで簡単にできる手順を解説

    ネットワーク上に複数のデバイスが接続されていると、自分のiPhoneを識別するのが難しく感じることはありませんか?実は、iPhoneの名前を変更しておけば、AirDropやBluetoothなどのリストの中からでも、目的のデバイスを素早く簡単に見つけられるようになります。 AppleはiPhoneの名前を変更するための簡単な方法を用意しています。この記事では、その具体的な手順をわかりやすく解説します。 iPhoneの名前を変更すべき理由とは? iPhoneの名前を変更したい理由は人それぞれです。例えば、以下のようなケースが挙げられます。 AirDropのリストで自分のデバイスが見つけにくい

  2. iOS 14の厳選8つの新機能――ホーム画面の刷新からプライバシー保護まで徹底解説

    2020年9月にリリースされたiOS 14は、新しい機能の追加、ホーム画面デザインの全面刷新、既存アプリのアップデートなど、iPhoneの歴史の中でも特に大きな進化を遂げたバージョンです。この記事では、対応するiPhoneをお持ちの方に向けて、iOS 14の魅力的な新機能とその活用方法を詳しくご紹介します。 自分のiPhoneはiOS 14に対応している? iOS 13が動作していたiPhoneであれば、iOS 14も問題なく動作します。ただし、古い機種の場合は一部の最新機能(特にカメラ関連のアップデート)が利用できないことがあります。 以下がiOS 14アップデートに対応しているiPhone