PIYO - Tech & Life -

Rails周りで最近知ったこと 2018/04版

Ruby Rails

String#squish

ActiveSupportで定義されているらしい。

def squish
  dup.squish!
end

def squish!
  gsub!(/[[:space:]]+/, " ")
  strip!
  self
end

halt_callback_chains_on_return_false がDeprecatedになった件でプルリク見てたら書いてあってみつけた。

deprecate halt_callback_chains_on_return_false instead of `halt_and… · rails/rails@4e63ce5

ActiveSupport::Deprecation.warn(<<-MSG.squish)
  ActiveSupport.halt_callback_chains_on_return_false is deprecated and will be removed in Rails 5.2.
MSG

ヒアドキュメントの余計な空白とか消すのに使うんだね。

window_opened_by

Capybaraでリンクをクリックしたときに別タブが開いて、みたいなときに使えるメソッドがあった。

Method: Capybara::Session#window_opened_by — Documentation for jnicklas/capybara (master)

within_windowと組み合わせて使える。

Method: Capybara::Session#within_window — Documentation for jnicklas/capybara (master)

こんな感じ。

scenario do
  visit root_path
  window = window_opened_by { click_lick '新しいタブで開く' }
  within_window(window) do
    expect(page).to have_content '新しいタブだよ'
  end
end

remote_ip

接続元のIPでアクセス制限するみたいなコードを書く時に、request.remote_ipを使ってました。環境構成がシンプルなときはそれでいけてました。

remote_ip (ActionController::Request) - APIdock

最近触ったアプリケーションが、CloudFrontを通ったりなんだりいろいろ経由してからRailsに到達する構成だったので接続元(ユーザーの環境)のIPがremote_ipで取れないことがありました。

調べてみると、経由した順にrequest.headers['X-Forwarded-For']にカンマ区切りで入っていることが判明。環境に合わせて取り出せるように、こんな風にしてIPを取り出せることがわかりました。

def client_ip
  @client_ip ||= (request.headers['X-Forwarded-For'].to_s.gsub(' ', '').split(',').first || request.remote_ip)
end

HTTP_X_FORWARDED_FORに入ってるんですねー。HTTPの仕様、一通り知らないといかんな。。。