グロースエンジニアのブログ

プログラミングとウェブ解析をやっています。Googleアナリティクス好きなRuby on Rails エンジニアです!

第56回 Ginza.rbに行ってきた!

ここ数ヶ月続けて Ginza.rb に参加しています。

自分とのレベルが違いすぎて圧倒されることが多いんですが、このままだと本当にただ参加しているだけになってしまうので、振り返りもかねて学んだことを記録して行こうと思います。

今回のテーマ

【第56回 もうすぐやってくる!Rails5.2の細かいところも見ておこう 】ということで、資料はこちら!(公開してもいいということだったので大丈夫なはず!)

Rails 5.2

内容については上記資料を見た方がいいです。

各ページの青いところはリンクになっていて関連するPRなどに飛べるので分かりやすいと思います。(さすが、あの方の資料!)

以下、自分用のメモ。
知らなかった機能などはざっとどんな機能か調べてリンクを貼ってます。

(間違いなどあればご指摘いただけるとうれしいです!)

Action Cable

- hostとかportとかを設定できるようになった

使ったことないけど、今後機会があれば思い出せるようにメモ。

Action Mailer

- Mailer ごとに delivery job を設定できる

`delivery_later` したときに呼ばれるjobを自由に設定できるってことかな?

rails/message_delivery_test.rb at 2b35826389005bdb0af85a4ebb1f0ec213174d13 · rails/rails · GitHub


- email preview にlocaleが選べるようになった

preview 機能自体を知らなかった...。

ActionMailer Preview のススメ - Qiita

RailsのAction Mailer Previewsについて | 日々雑記

Action Pack

- cache key と cache version(updated_at)を分けて管理し、 cache keyを再利用可能に

Rails の version up のときに、load default にするとあれするので気を付けてね!とのこと。

ローカルで試すには設定が必要っぽい。

キャッシュは、デフォルトではproduction環境でのみ有効になります。ローカルでキャッシュを使ってみたい場合は、対応するconfig/environments/*.rbファイルでconfig.action_controller.perform_cachingtrueに設定します。

Rails のキャッシュ: 概要 | Rails ガイド

- eager_load = true の場合、サーバー起動時に各コントローラーのactionを読み込むようになった

- encrypted cookies に AES-256-GCM を使用

より堅牢なものになった
Rails側で良いようにしてくれる(自動で書き換える)
勝手に古いcookies を新しいものに書き換える

- protect_from_forgery がデフォルトになった

- signed/encrypted cookiesに有効期限を知っていできる

- key の rotation ができるようになった

# ここで新しいものを指定
Rails.application.config.action_dispatch.signed_cookie_digest = "SHA256"

# ここで古いのを指定
Rails.application.config.action_dispatch.cookies_rotations.tap do |cookies|
  cookies.rotate :signed, digest: "SHA1"
end

- System test に headless chrome driver, headless firefox driver が入った

- デフォルトの mime type が追加された

- header が変わった
以下の3つが追加された


  "X-Download-Options" => "noopen",
  "X-Permitted-Cross-Domain-Policies" => "none",
  "Referrer-Policy" => "strict-origin-when-cross-origin"

Action View

- srcset を指定できるようになった

- 画像の alt の自動生成を削除

- form_with に id 属性を追加するようになった
capybara のテストなどで必要ということで追加された 

Active Job

jobを実行する際にオブジェクトをシリアライズ、デシリアライズしてる。
それを自分で定義できるようになった

Active Model

- length validatorにProc, Symbolが渡せるようになった
これにより、条件を指定して最大文字数とかを調整できるようになった

- Active Record にあった attributes API が Active Model 配下に移動
Active Record のものを使うのは問題ない
Active Model のものは public ではない

(Rails で public api ってのは docs にあるかどうか)

Active Record

- Descending Indexが指定できるようになった(MySQL 8.0.1以降)

- sqlite3 で boolean を t/f から 1/0 に修正
t/f で保存していた場合、手動で変更する必要がある

- order と pluck に生 SQL はダメ
Arel.sqlメソッドでラップしないとだめ

- fixtures でまとめてクエリーを実行するようになった

- SQLが発行された場所が log に出るようになった
デフォルトは開発環境のみ

- MySQL の bulk true があったけど、 PostgreSQL でもできるようになった

- PostgreSQL の foreign tables をサポート

- Errorクラスが増えてる

https://y-yagi.github.io/presen_rails_5_2_part2/#/47

- その他、 Active Record はこれを見ると良い
http://kamipo.github.io/talks/20180215-tdtech/#/title

Atcive Support

- Date#prev_occurring、Date#next_occurringメソッドが追加された
前の曜日、次の曜日を取得するメソッド

- ActiveSupport::Cache::Store に write_multi メソッドを追加
Redis adapterだとMSETを使うようになるので、一個一個書き込むよりはやい

- ActiveSupport::Testing::TimeHelpersをincludeしている場合、テストの後処理で自動でtravel_backが呼ばれるようになった
Rspec はどうするのかわからない

Railties

- rails new 時の Gemfile に bootsnap を追加

--skip-bootsnap でスキップできる

その後の飲み会

今回は知った人が多かったので飲み会にも参加!

自分の開発経験にはない話がいっぱい出てきて、とても勉強になった。前に一回参加したときも感じたけど、こういう中での話にも知らないことがいっぱい出てくるので聞いてるだけで楽しい!

また参加します!

2017年を振り返って

今年は一年マルっとフリーランス プログラマーとして活動した年だった。

周りの人には言っているが、リサーチをやっていたときには全く考えていない働き方だし、こんなに楽しく仕事ができるようになったのも想像してなかったので、今の気持ちを整理したいと思う。

フリーになりたてのころ

正確には、去年(2016年)の10月からフリーになった。

当初はリサーチ業界から転職してプログラマーとしての仕事は2年くらいで不安しかなかった。

  • こんなんで仕事できるの?
  • コード理解できるかな?
  • コード書けるかな?

この時期は、まだプログラマーなりたてだし...って自分に言い訳をしてたのもあった。

一年を振り返った今の気持ち

この一年で合計3社さんとお仕事させてもらって、不安は少しずつ減ってきた。

それぞれの会社さんで実装面で相談にのってもらったり、知識不足のところは教えてもらったり、たくさんの人に助けてもらって、それまで「俺にできるのか?」って思ってたことでも「何とかできそう!」って思えるようになってきた。

今でも不安な気持ちはあるし、アウトプット出せてないときは本当に申し訳なく思う。だからこそ、もっと勉強しないといけないと思うし、期待されて、その期待以上のものを出すプログラマーになりたいなと思う。

いつからこんなに勉強することが楽しくなったのか、自分でも不思議なくらい本を読んだりコードを書くようになったのも事実で、まだまだ楽しく仕事できるな〜って感じている。

(それぞれの会社でお世話になった方々、ありがとうございました。)

反省点

性格的に怖がりで失敗したくないので、今ある知識の中で何とかしようとする部分が多かった。

でも、一回経験しておくと二回目以降に安心して手が動くという経験を何度もしたので、新しく勉強したものを「何でそれがいいのか?」という部分をちゃんと理解しつつ、実際のプロダクトのコードで使っていくようにした方がよかった。

来年やること

フロントとインフラ

あれこれ他の言語に手を出さず、自分で意図的に Rails だけやってきたのでここは強みだと思う反面、他の言語とかフロント、インフラ周りになるとなかなかアウトプット出せないなって感じた...

フロントと最低限のインフラ知識は必要だなと思うので、この辺りは自プロダクトも含めて埋めていきたい。

RubyRails

そして、 Rails 周りのインプットを増やせば増やすほど、こんな書き方できるのか!こうやって model を分けるのか!とか新しい発見が多くて、もっと知っていい感じのコード書けるようになりたいと思った。

なので、本やサイトから RubyRails 周りのインプット・アウトプットは今後も続けつつ、OSSのコードを読んでいろんな書き方を学びつつ、OSS貢献もやっていきたい。

また、人が多いところが苦手で勉強会とかにあまり参加していなかったので、来年は参加する機会を増やしていこうと思う。

ブログ

今年は全く書いてなかった。

こんなこと書いてもな〜...って思うこともあったけど、今でも昔の記事読むと、しょーもな!って思うことで悩んだりしてたみたいなので、作業ログ的に記録を残しておくと、「この当時はこんなことで悩んどったんだな」とかあとあと振り返りがしやすいかなと思う。

自分の記録を残すって意味でも、もう少し何かしら書いていこうと思う。

自プロダクト

自分のプロダクトとして Growth Support を作った。いいプロダクトになると思っているので開発を進めてさらにいいものにしていきたい。

また、くだらないサービスもどんどん作って公開していきたいと思う。その過程で知識不足なフロントとインフラを埋めていければいいと思っている。

まとめ

そんなこんなで、今年はとても楽しい一年だった。

やることもたくさんあるし、知りたいこともいっぱいある。まだまだプログラマーとして楽しい日々が送れそうなので、来年はもっと楽しい一年にしたいと思う。

webpack2 : チュートリアルをやってみた!

最近よく聞く webpack !

いろんなプロジェクトで使われてて裏でいい感じに動いていて勉強しないとと思って数ヶ月...やりました!

バージョンが 2 になってたみたいで、チュートリアルやったら動かなくて困った...

とりあえず以下を参考に動くところまでは持っていった!

 

webpack.js.org

で、初心者なのでここからどうしよう...と思って見つけたのがこのチュートリアル!なのでこれをやってみました!

Getting Started with webpack 2 – Thinking in Code

今の状態としては、webpack の Getting Started をやって終わっている状態です!

- webpackのバージョンは 2.3.2

yarnを使う

これも聞いたことがある!パッケージマネージャらしい!

Yarn is a package manager for your code.

yarnpkg.com

以下を実行すると yarn が使えるようになるっぽい。

brew install yarn
yarn add --dev webpack webpack-dev-server@2

 

基本的には記事通りにやって行けば大丈夫だと思うけど、動かなかったところをメモしていく!

webpack-dev-server

これも当たり前なんかな?普通にターミナルに入力して動かなくて、以下のコマンドでインストール後に動いた。

npm install -g webpack-dev-server

 

extract-text-webpack-plugin

記事内では beta 版が使われているようだったけど、今は大丈夫っぽい!

npm install --save-dev extract-text-webpack-plugin

github.com

まとめ

とりあえず動くようになったけど、実際にコード書いていかないと分からないな(笑)

これからいじっていく予定!

【Rails5】devise でログイン後ページをユーザー意図に合わせて変更する

前回の記事でログイン後ページのリダイレクトを設定しました。

ログアウトした状態でログイン後の特定ページにいった場合、ログインページに遷移し、ログインするとその設定したページにリダイレクトされます。

しかし、その場合ユーザーとしてはログインするとそのログイン後の特定ページにリダイレクトされたいと思います。

今回はその機能を実装していきます。

ログイン前のページを保存する

以下のページで解説がありますので、そのとおりに実装していきます。

How To: Redirect back to current page after sign in, sign out, sign up, update · plataformatec/devise Wiki · GitHub

まず app/controllers/application_controller.rb に以下を追記します。

class ApplicationController < ActionController::Base
before_action :store_current_location, unless: :devise_controller?
before_action :authenticate_user!

...

private

def store_current_location
store_location_for(:user, request.url)
end
end

これでログイン前のページが保存されます。

ログイン後のリダイレクトを修正

次に以下のようにしてログイン後のリダイレクトを先ほどの保存したログイン前ページを使うように修正します。

  def after_sign_in_path_for(resource)
stored_location_for(resource) || mypage_root_path
end

ログイン不要ページを除く

この設定でほぼOKなんですが、ログインが不要なページからログインページに遷移した場合もこの機能が働きます。

例えば、トップからログインページに遷移した場合、ログイン後はトップに戻ります。しかし、ここではログイン後のトップ(上記例では mypage_root_path)に遷移させたいと思います。

なので、その設定を行います。なお、ここではログイン不要のページ(トップページ)を home_controller で設定しているとします。

class ApplicationController < ActionController::Base
before_action :store_current_location, unless: :devise_or_home_controller?
before_action :authenticate_user!

...

private

...

def devise_or_home_controller?
devise_controller? || controller_name == 'home'
end
end

これで home_controller は保存されなくなり、意図通り mypage_root_path に遷移します。 controller_name == 'home' の部分はもう少しやりようがある気がしてますが、ひとまず、これで動きます。

それ以外でいい方法があれば教えてください!

ということで今回はここまで。

 

devise 関連記事はこちら

【Rails5】devise でログイン機能を実装する

【Rails5】devise を日本語化する

【Rails5】devise でログイン後、ログアウト後のページを設定する

【Rails5】gem omniauth-google-oauth2 のrspecテストではまった

ログインテストを書いていてハマったのでメモ。

以下を参考にテストを書いていた。

Integration Testing · omniauth/omniauth Wiki · GitHub

Rails + Devise + OmniAuth で Facebook/Twitter の OAuth 認証を RSpec + Capybara でインテグレーションテスト(RequestSpec) | EasyRamble

How to Test Drive OmniAuth Google OAuth2 for your Rails App — Jesse Spevack

 

なるほど!なるほど!と思いながら真似してやっていたが、上手く行かず...

rspec 内に binding.pry を仕込んで中を見てみると上手く設定できてないみたいで、デフォルトのパラメータが返ってくる。

[3] pry(#<Users::OmniauthCallbacksController>)> request.env['omniauth.auth']
=> {"provider"=>"default",
"uid"=>"1234",
"info"=>{"name"=>"Example User"}}

omniauth-google-oauth2 を使っている場合は google_oauth2

原因は mock を作るときに以下のように google を設定していたこと。

OmniAuth.config.mock_auth[:google]

これを google_oauth2 に修正したら上手くいきました!

OmniAuth.config.mock_auth[:google_oauth2]

mock を使ったテスト自体ほとんど書いたことがなかったので、これを解決するのにハマってしまった...

【Rails5】devise でログイン後、ログアウト後のページを設定する

ユーザーがログインした後、ログアウトした後のページへの遷移をデフォルトのものから変更したいと思います。

以下のページの項目を読むと after_sign_in_path_for と after_sign_out_path_for をオーバーライドしてねってあるので、その通りやっていきます。

GitHub - plataformatec/devise: Flexible authentication solution for Rails with Warden.

application_controller.rb に追記

以下のように after_sign_in_path_for にログイン後のページ、 after_sign_out_path_for にログアウト後のページを設定するとリダイレクトしてくれます。

class ApplicationController < ActionController::Base
before_action :authenticate_user!

def after_sign_in_path_for(resource)
mypage_root_path # ログイン後に遷移するpathを設定
end

def after_sign_out_path_for(resource)
new_user_session_path # ログアウト後に遷移するpathを設定
end
end

思ったよりサクッといけました!

 

devise 関連記事はこちら

【Rails5】devise でログイン機能を実装する

【Rails5】devise を日本語化する

【Rails5】devise でログイン後ページをユーザー意図に合わせて変更する

【Rails5】devise を日本語化する

前回はログイン機能の実装を行いましたが、今回はこれを日本語化していきたいと思います。

デフォルトのロケールを設定する

deviseのページに方法が書いてあるので、これどおりにやっていきます。

I18n · plataformatec/devise Wiki · GitHub

config/application.rb にデフォルトのロケールを設定します。

config.i18n.default_locale = :ja

デフォルトで何か設定されている場合は修正してください。

 日本語化ファイルを設定する

config/locales/devise.ja.yml というファイルを作成し、上記ページにある日本語翻訳ファイルをコピペします。 

# Additional translations at https://github.com/plataformatec/devise/wiki/I18n

ja:
  devise:
    confirmations:
      confirmed: 'アカウントを登録しました。'
      send_instructions: 'アカウントの有効化について数分以内にメールでご連絡します。'
      send_paranoid_instructions: "あなたのメールアドレスが登録済みの場合、本人確認用のメールが数分以内に送信されます。"
    failure:
      already_authenticated: 'すでにログインしています。'
      inactive: 'アカウントが有効化されていません。メールに記載された手順にしたがって、アカウントを有効化してください。'
      invalid: "%{authentication_keys} もしくはパスワードが不正です。"
      locked: 'あなたのアカウントは凍結されています。'
      last_attempt: 'あなたのアカウントが凍結される前に、複数回の操作がおこなわれています。'
      not_found_in_database: "%{authentication_keys} もしくはパスワードが不正です。"
      timeout: 'セッションがタイムアウトしました。もう一度ログインしてください。'
      unauthenticated: 'アカウント登録もしくはログインしてください。'
      unconfirmed: 'メールアドレスの本人確認が必要です。'
    mailer:
      confirmation_instructions:
        subject: 'アカウントの有効化について'
      reset_password_instructions:
        subject: 'パスワードの再設定について'
      unlock_instructions:
        subject: 'アカウントの凍結解除について'
      password_change:
        subject: 'パスワードの変更について'
    omniauth_callbacks:
      failure: "%{kind} アカウントによる認証に失敗しました。理由:(%{reason})"
      success: "%{kind} アカウントによる認証に成功しました。"
    passwords:
      no_token: "このページにはアクセスできません。パスワード再設定メールのリンクからアクセスされた場合には、URL をご確認ください。"
      send_instructions: 'パスワードの再設定について数分以内にメールでご連絡いたします。'
      send_paranoid_instructions: "あなたのメールアドレスが登録済みの場合、パスワード再設定用のメールが数分以内に送信されます。"
      updated: 'パスワードが正しく変更されました。'
      updated_not_active: 'パスワードが正しく変更されました。'
    registrations:
      destroyed: 'アカウントを削除しました。またのご利用をお待ちしております。'
      signed_up: 'アカウント登録が完了しました。'
      signed_up_but_inactive: 'ログインするためには、アカウントを有効化してください。'
      signed_up_but_locked: 'アカウントが凍結されているためログインできません。'
      signed_up_but_unconfirmed: '本人確認用のメールを送信しました。メール内のリンクからアカウントを有効化させてください。'
      update_needs_confirmation: 'アカウント情報を変更しました。変更されたメールアドレスの本人確認のため、本人確認用メールより確認処理をおこなってください。'
      updated: 'アカウント情報を変更しました。'
    sessions:
      signed_in: 'ログインしました。'
      signed_out: 'ログアウトしました。'
      already_signed_out: '既にログアウト済みです。'
    unlocks:
      send_instructions: 'アカウントの凍結解除方法を数分以内にメールでご連絡します。'
      send_paranoid_instructions: 'アカウントが見つかった場合、アカウントの凍結解除方法を数分以内にメールでご連絡します。'
      unlocked: 'アカウントを凍結解除しました。'
  errors:
    messages:
      already_confirmed: 'は既に登録済みです。ログインしてください。'
      confirmation_period_expired: "の期限が切れました。%{period} までに確認する必要があります。 新しくリクエストしてください。"
      expired: 'の有効期限が切れました。新しくリクエストしてください。'
      not_found: 'は見つかりませんでした。'
      not_locked: 'は凍結されていません。'
      not_saved:
        one: "エラーが発生したため %{resource} は保存されませんでした:"
        other: "%{count} 件のエラーが発生したため %{resource} は保存されませんでした:"

これで devise に関連する表示は日本語化できました。

モデルも日本語化する

ついでと言っては何ですが、フォームなどに表示される項目も日本語化していきたいと思います。

Email や Password といった表示はモデルの属性によるものなので、 config/locales/models.ja.yml などのファイルを作成し、以下を追記します。

ja:
  activerecord:
    attributes:
      user:
        email: メールアドレス
        password: パスワード
        password_confirmation: 確認用パスワード
remember_me: 次回から自動的にログイン

これでフォームに表示される項目も日本語化できます。

それ以外の日本語化

それ以外の箇所は直接viewにかかれているようなので、それを修正すればいいかと。必要に応じて I18n 化する感じです。

例えば app/views/devise/sessions/new.html.erb がログインフォームなので、このファイルを開いて日本語に書き換えます。

<h2>ログイン</h2>
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
</div>

<div class="field">
<%= f.label :password %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>

<% if devise_mapping.rememberable? -%>
<div class="field">
<%= f.check_box :remember_me %>
<%= f.label :remember_me %>
</div>
<% end -%>

<div class="actions">
<%= f.submit "ログイン" %>
</div>
<% end %>

<%= render "devise/shared/links" %>

 一番最後にある devise/shared/links はフォームの最下部にあるリンクを作成している viewなので、これも必要に合わせて修正してください。

 

以上、 devise の日本語化でした!

 

devise 関連記事はこちら

【Rails5】devise でログイン機能を実装する

【Rails5】devise でログイン後、ログアウト後のページを設定する

【Rails5】devise でログイン後ページをユーザー意図に合わせて変更する