Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

週刊Railsウォッチ(20191118前編)ActiveJob引数のログ抑制、RailsガイドProプランお試し、ファイルアップロードのレジュームgemほか

こんにちは、hachi8833です。銀座Rails #15やっぱり行けばよかった😢。

  • 各記事冒頭には⚓でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ
  • 「つっつきボイス」はRailsウォッチ公開前ドラフトを(鍋のように)社内有志でつっついたときの会話の再構成です👄
  • 毎月第一木曜日に「公開つっつき会」を開催しています: お気軽にご応募ください

今回のウォッチは第16回公開つっつき会を元にお送りいたします。ご参加いただいた皆さまありがとうございました!差し入れいただいて感激です😂。

Rails: 先週の改修(Rails公式ニュースより)

今回はコミットリストから見繕いました。


つっつきボイス:「6.0.1リリースから間もないせいか、小さ目のパッチが中心のようです」「明日の銀座Railsのネタ仕込まないといけないの思い出した😅」

新機能: 重要な情報を引数とするジョブでログ出力を抑制するオプションを追加

ジョブがキューに入るときやジョブ実行時に、ジョブの引数のログ出力を無効にするオプションを追加した。
CHANGELOGより大意

class SensitiveJob < ApplicationJob
  self.log_arguments = false

  def perform(my_sensitive_argument)
  end
end

つっつきボイス:「今まではジョブのログに出ちゃってたのか😳」「例のfilter_parameters↓的なことをジョブのログでもやりたいということでしょうね☺️」

参考: 13.1 パラメータをフィルタする -- Action Controller の概要 - Rails ガイド

# config/initializers/filter_parameter_logging.rb
config.filter_parameters += :password

「(ゲストの方に)背景を説明しておくと、これはパスワードのような重要な情報をログに出さないための仕組みの話ですね: せっかく他のセキュリティを頑張っても、ログに生のパスワードとかが全部出てたりすると、仮に侵入されたときにログファイルだと楽勝で読めてしまうので、あ...終了😇なんてことがまれによくあったりします😆」「お〜😅」

「フォームに値を入力して送信すると原則としてパラメータ(params)がログ出力されるんですけど、Railsには前述のような問題を防ぐ仕組みとして前からfilter_parametersというものがあって、デフォルトではpasswordという文字をパラメータ名に含む場合は、ログに出すときに値をXXXXみたいに伏せ字にしてくれます」「なるほど!」「今回の改修はそれをジョブの引数についても同じようなことをやれるようになったということですね☺️」

「この改修って割と重要ですよね😆」「一部の人にとっては😆」

スレッドでのdeprecationメッセージ出力を修正

# activesupport/test/deprecation_test.rb#L293
+ def test_silence_threaded
+   barrier = Concurrent::CyclicBarrier.new(2)
+
+   th = Thread.new do
+     ActiveSupport::Deprecation.silence do
+       barrier.wait
+       barrier.wait
+       assert_not_deprecated { ActiveSupport::Deprecation.warn "abc" }
+     end
+     assert_deprecated("abc") { ActiveSupport::Deprecation.warn "abc" }
+   end
+
+   barrier.wait
+
+   assert_deprecated("abc") { ActiveSupport::Deprecation.warn "abc" }
+
+   ActiveSupport::Deprecation.silence do
+     assert_not_deprecated { ActiveSupport::Deprecation.warn "abc" }
+   end
+
+   assert_deprecated("abc") { ActiveSupport::Deprecation.warn "abc" }
+
+   barrier.wait
+   th.join
+ ensure
+   th.kill
+ end

つっつきボイス:「ActiveSupport::Deprecation.silenceがスレッドローカルになってなかったのでConcurrent::ThreadLocalVar↓を使うようにしたのかなと☺️」「そういえばちょっと前にもConcurrentを使った改修がありましたね😳(ウォッチ20190909)」

# activesupport/lib/active_support/deprecation.rb#L38
    def initialize(deprecation_horizon = "6.2", gem_name = "Rails")
      self.gem_name = gem_name
      self.deprecation_horizon = deprecation_horizon
      # By default, warnings are not silenced and debugging is off.
      self.silenced = false
      self.debug = false
+     @silenced_thread = Concurrent::ThreadLocalVar.new(false)
    end

RailsアプリでConcurrent Rubyを使う(翻訳)

「でもdeprecation warningなんだし、そうまでして直さなくてもいいような気もしますけど😆」「この修正がないととても困るという気はあまりしない😆」「マルチスレッドで一部についてだけdeprecation warningを出して、それ以外では抑制したいときとか?」「特定IPのときだけdeprecation warningを出したいとか?😆」「どうしても欲しいシチュエーションがあんまり思いつかない〜🤣」「欲しい人がいるのはわかるけど😆」

「たとえばRailsの移行中とかで、warningを承知のうえで抑制したいけど全部抑制すると後で追えなくなるから欲しくなったとかですかね?☺️」「移行中に自分たちでwarningをある程度制御しておきたいみたいな」「Pumaとかでマルチスレッドで回しているときにこの問題に気づいたとかはあるかも🤔」「せやなと言うしかない😆」

従来はActiveSupport::Deprecation.silence { ... }がすべてのスレッドのdeprecationメッセージを抑制するので、マルチスレッド環境でびっくりする人もいると思う。
ActiveSupport::Deprecation.silenced=はグローバルオプションに設定を残すので少々紛らわしい可能性もあるが、これにはさまざまな用法があるのでこの方法が最もうまく一般的な用法を変えずに済むと思われる。silence {}はコードの小さなセクションのメッセージを抑制し、silenced=はイニシャライザやテストヘルパーでデフォルト設定に用いることが多い。
自分としてはActiveSupport::Deprecation.silenced=を非推奨にして代わりにActiveSupport::Deprecation.behavior = :silenceを使うべきかもしれないとふんわり思っている(絶対そうすべきとまでは思っていないし、このプルリクの趣旨から外れる)。
同PRより大意

新機能: travel_backテストヘルパーがブロックを取れるようになった

# activesupport/lib/active_support/testing/time_helpers.rb#L42
+     def stubbed?
+       !@stubs.empty?
+     end
...
      def travel_back
+       stubbed_time = Time.current if block_given? && simple_stubs.stubbed?
+
        simple_stubs.unstub_all!
+       yield if block_given?
+     ensure
+       travel_to stubbed_time if stubbed_time
+     end

# 同コミットより
Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00

travel_to Time.zone.local(2004, 11, 24, 01, 04, 44)
Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00

travel_back do
  Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
end

Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00

つっつきボイス:「travel_backは時間を巻き戻すヤツでしたね」「ブロックの最終評価値を使ってtravel_backを設定できるようになった😋」「これはわかる〜😋」

参考: travel_back -- ActiveSupport::Testing::TimeHelpers

# api.rubyonrails.orgより
Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
travel_to Time.zone.local(2004, 11, 24, 01, 04, 44)
Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
travel_back
Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00

「Railsでテストとかで現在時刻を違う時間に設定するのにtravel_toというメソッドを使うのがRailsらしいですよね☺️」「列車の比喩で『旅』『時間旅行』にかけた感じ😆」

参考: travel_to -- ActiveSupport::Testing::TimeHelpers

# api.rubyonrails.orgより
Time.current     # => Sat, 09 Nov 2013 15:34:49 EST -05:00
travel 1.day
Time.current     # => Sun, 10 Nov 2013 15:34:49 EST -05:00
Date.current     # => Sun, 10 Nov 2013
DateTime.current # => Sun, 10 Nov 2013 15:34:49 -0500

Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
travel 1.day do
  User.create.created_at # => Sun, 10 Nov 2013 15:34:49 EST -05:00
end
Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00

「これはテストコードで使うんでしょうか?」「時刻に依存するテストを書きたいときなんかに使いますね☺️」「travel_toで現在時刻を別の時間に変えるんですけど、それを元に戻したいときにtravel_backします⏱」「なるほど〜」「業務アプリを書いていると時刻系はよくハマります🧐」

travel_backは以下の記事にも登場してますね。

Rails: Timecopを使わなくても時間を止められた話

やはりというか原田真二の「タイム・トラベル」という懐メロを思い出しました👨。

「そういえばtimecopってありましたね」「以前はtimecopでやってましたが今はActiveSupportでやれます👍」

時間警察はドラえもんで知りましたが、古くはポール・アンダースン「タイムパトロール」、最近だと仮面ライダーG電王なんですね😳。

参考: タイムパトロール - Wikipedia
参考: 仮面ライダー×仮面ライダー×仮面ライダー THE MOVIE 超・電王トリロジー - Wikipedia

HTTPトークン認証の解説をガイドに追加

# rails/actionpack/lib/action_controller/metal/http_authentication.rb#L405
    module Token
      TOKEN_KEY = "token="
      TOKEN_REGEX = /^(Token|Bearer)\s+/
      AUTHN_PAIR_DELIMITERS = /(?:,|;|\t+)/
      extend self
...

つっつきボイス:「RailsガイドにBASIC認証とダイジェスト認証の説明はあったのにトークン認証の説明がなかったので追加したそうです」「機能は前からあったんですね😳」

トークン認証

HTTPトークン認証は、HTTP AuthorizationヘッダーでBearerトークンの利用を有効にするスキームです。さまざまな形式のトークンを利用可能ですが、詳細は本ドキュメントの範疇を超えます。
たとえば、以下のように事前発行された認証トークンを使って認証やアクセスを実行したいとします。Railsでのトークン認証の実装はauthenticate_or_request_with_http_tokenというメソッド1つでやれるのでとても簡単です。

class PostsController < ApplicationController
  TOKEN = "secret"
  before_action :authenticate
  private
    def authenticate
      authenticate_or_request_with_http_token do |token, options|
        ActiveSupport::SecurityUtils.secure_compare(token, TOKEN)
      end
    end
end

authenticate_or_request_with_http_tokenは上述の例のように2つの引数「トークン」「Hash(HTTP Authorizationヘッダーから取り出したオプションを含む)」を取ります。認証が成功したらこのブロックはtrueを返します。falseまたはnilが返ると認証は失敗です。
同PRより大意

「トークン認証って何だろう?🤔」「Authorizationにトークンを突っ込むだけで使える🧐」「SSOサーバーを自分で実装するときとかに使うのかなと推測🤔」「Authorizationヘッダーでサポートされてるなら大丈夫そう」「Railsガイドに記載されていない機能って結構ありますよね😆」「こういうのが増えるのはありがたい🙏」

参考: RFC 6750 - The OAuth 2.0 Authorization Framework: Bearer Token Usage -- トークン認証の仕様
参考: トークンを利用した認証・認可 API を実装するとき Authorization: Bearer ヘッダを使っていいのか調べた - Qiita

トークンはtoken68の仕様↓に沿っていればよいようです。

参考: token68

class_method_defined_withinをリファクタリング

# activerecord/lib/active_record/attribute_methods.rb#L117
      def dangerous_class_method?(method_name)
-       RESTRICTED_CLASS_METHODS.include?(method_name.to_s) || class_method_defined_within?(method_name, Base)
-     end
+       return true if RESTRICTED_CLASS_METHODS.include?(method_name.to_s)

-     def class_method_defined_within?(name, klass, superklass = klass.superclass) # :nodoc:
-       if klass.respond_to?(name, true)
-         if superklass.respond_to?(name, true)
-           klass.method(name).owner != superklass.method(name).owner
+       if Base.respond_to?(method_name, true)
+         if Object.respond_to?(method_name, true)
+           Base.method(method_name).owner != Object.method(method_name).owner
          else
            true
          end
        else
          false
        end
      end

つっつきボイス:「シンプルなリファクタリングのようです」「1箇所でしか呼んでないメソッド要らんだろということでインライン化した感じですね☺️」

match?starts_withends_withに変更


つっつきボイス:「最近も似たような修正あったような🤔」「こういうふうにmatch?start_with?に置き換えたり↓」「地道なマイクロ最適化ですね☺️」

# actionpack/test/dispatch/exception_wrapper_test.rb
    setup do
      @cleaner = ActiveSupport::BacktraceCleaner.new
      @cleaner.remove_filters!
-     @cleaner.add_silencer { |line| !line.match?(/^lib/) }
+     @cleaner.add_silencer { |line| !line.start_with?("lib") }
    end

「正規表現は一般にパフォーマンスがあまり出ないので『〜で始まる文字』みたいなチェックは専用の文字列メソッドの方がわかりやすいし速いですね😋」「特に前方一致は明らかに違い出ますね🧐」

「2つ目はto_jsonstart_with?が効かなかった問題を修正したそうです↓」「こういうのってたまに踏む😆」「ありがたい🙏」「OptionMergerは暗黙で使われるから知らないうちに踏んでたかも😅」

# activesupport/lib/active_support/option_merger.rb#L5
module ActiveSupport
  class OptionMerger #:nodoc:
    instance_methods.each do |method|
-     undef_method(method) unless method.start_with?("__", "instance_eval", "class", "object_id")
+     undef_method(method) unless method.to_s.start_with?("__", "instance_eval", "class", "object_id")
    end

Ruby: 文字列マッチは正規表現より先に専用メソッドを使おう

たぶんこちらも関係してそうです↓。

ポリモーフィック関連付けで:polymorphic:as:foreign_typevalid_optionsに追加した

# activerecord/lib/active_record/associations/builder/belongs_to.rb#L9
    def self.valid_options(options)
-     super + [:polymorphic, :counter_cache, :optional, :default]
+     valid = super + [:counter_cache, :optional, :default]
+     valid += [:polymorphic, :foreign_type] if options[:polymorphic]
+     valid
    end

つっつきボイス:「@kamipoさんの修正です」「Active Recordのこの辺のコードを単体で見てもまるでわからん😆」「😆」「何ができるようになるのやら😆」

y-yagiさんのブログに、これを含めたvalid_options関連のkamipoさんの修正がまとまっていました。

参考: rails commit log流し読み(2019/11/10) - なるようになるブログ

「今Active Record周りを勉強し始めているところなんですけど、上のコードはActive Recordの中身の話なんでしょうか?」「そうですね、Active Recordはこう書かれているというヤツです」「こういうところを読んでくとActive Recordがどう振る舞うかわかるようになるんでしょうか?」「この辺の改修を眺めるというのはどちらかというと、Railsでアプリを開発していてたまたまRailsのバグを踏んだり、うっかりRailsが想定していない書き方をして謎のエラーを出してしまったときなんかに役に立つこと『も』あるという感じです」「あ〜そうでしたか😳」「普通にRailsアプリのコードを書いている分には9割必要ないと思います😆」「😆」

「それでもどういう改修があったかを追っていくことには一定のメリットがありますね: 新しい機能が入ったりバグが修正されたということは、安定版のRailsにはまだ入っていない機能なので、自分たちのところでバグが発現する可能性があるわけです」「ふむふむ」「改修を追っていると、自分がそういうバグを踏んだときに『あ、そういえばこのバージョンのRailsにはこんなバグがあった気がする』という既視感につながっていくので、そういうのがごくまれに役に立つことは、ある🤣」「🤣」「🤣」

「この修正は安定版にはまだ入ってないんですね😳」「改修はmasterブランチにまず入るんですけど、これはまだリリースされていない状態のブランチです: 今だと最新安定版(6-0-stableブランチ)は6.0.1なんですけど、masterはそれより進んだ状態になっていて、今後時期が来たらたとえば6.0.2というタグが打たれて次の最新安定版に入るという具合です」「なるほど😋」「今はrubygems.org↓でRailsを見ると6.0.1になっているので、rails newすると6.0.1が最新として入るようになってます」

参考: RubyGems.org | コミュニティのGemホスティングサービス

新機能: コネクションを管理するRoleManagerを導入

こちらはつっつきの後で気づきました😅。コードが長いので引用はしません。

このプルリクで追加したRoleManagerは複数のRolesを管理できる。各Roledb_configを持つ。
これによりpublic APIの改変を回避し、ハンドラやロールの概念を扱えるようにし、各クラスのハンドラごとに複数のコネクションを内部で確立するのに必要なものを達成する。
同PRより大意

Rails

RSpec 3.9がリリース


つっつきボイス:「いつの間にか3.9になってた😳」「rspec-railsだけ本体とバージョンが合わなくなる?」「rspec-railsは足並み揃えるよりどんどん改修入れる方を優先しようということですね☺️」

なお、私が今転生作業中のオレオレRailsアプリはこっそりminitestにしてます😆。

HerokuがSorbetをやってみてわかったこと(Ruby Weeklyより)


よかった点:

  • 結果を保存せずに同じメソッドを2回呼んでいたのを指摘
  • nullableなカラムを公開してたのを指摘
  • 雑にnilまたはtrueを返していたのを指摘

つっつきボイス:「HerokuがSorbetを使ってみたと」「4人チームで実験的にやってみた段階だそうですが、上のような点を見つけてくれたそうです😆」

「Sorbetはウォッチでも何度か取り上げましたが、RailsというよりRubyやってる人たちの間でアツい静的型チェッカーです😆」「😆」「Railsアプリを普通に分にはSorbetまだ知らなくても大丈夫かなと思いますが😆、とてもミッションクリティカルなアプリを書くときには必要になるかもしれませんね☺️」

「とりあえずアイスクリームアイコン🍨↓がかわいい❤️」


sorbet.orgより

「sorbet-rails試してみたかったんですが、なぜか今日のbundle installがえらく遅くて、しかも今見たらnot publicly available yetとか出てた😇」「😆」


その後うなすけさんの以下のスライドに今頃気づきました。

Basecampが無料個人版をリリース


basecamp.comより


つっつきボイス:「Basecampが個人版を?へぇ〜」「法人版だと価格的に見合わないので出したそうです」「completely freeって書いてますね」「マジで?」「見落としてた😅」「機能制限はあるけど無料!」「ストレージ1GBか〜😅」「個人なら十分かも」

「一応背景を説明すると、BasecampというのはRuby on Railsフレームワークの作者であるDHH(David Heinemeier Hanson)↓がいる会社で、一種のプロジェクト管理ツール的なサービスであるBasecampはもちろんRailsで提供しています」「日本ではあまり知られていませんけど😆」「日本だと(聞き取れず)が使ってるらしいけどネ」

「Basecampのサービスを何に例えたらいいかな🤔」「GitHubプロジェクトからソースコード管理を引いたような感じですかね〜☺️」「タスク管理とかチャットとかスケジュールとか」

「そしてBasecampに新しい機能が入ると、いずれその機能がRailsにも入ってくるということが割とあったりします😆」「へぇ〜」「たとえばRailsのAction CableはRails 4.xで入ったんですけど、それはBasecampにチャット機能が入ったからだろう、なんてことがよく言われます🤣」「😆」「Basecampを見てれば直近の未来がわかるかもしれないと」「BasecampはフルにRailsで書かれているはずなので知っておくといいと思います☺️」

参考: Action Cable の概要 - Rails ガイド

Skunk: 「コードの臭い」を数値化(Ruby Weeklyより)


つっつきボイス:「コードがどのぐらい臭ってるかを数値化するgemだそうです💩」「説明すると、『コードの臭い(code smell)』はプログラミングの世界ではダメなコードの書き方に対して使われます」

# 同リポジトリより
New critique at file:////Users/etagwerker/Projects/fastruby/skunk/tmp/rubycritic/overview.html
+-----------------------------------------------------+----------------------------+----------------------------+----------------------------+----------------------------+----------------------------+
| file                                                | stink_score                | churn_times_cost           | churn                      | cost                       | coverage                   |
+-----------------------------------------------------+----------------------------+----------------------------+----------------------------+----------------------------+----------------------------+
| lib/skunk/cli/commands/default.rb                   | 166.44                     | 1.6643999999999999         | 3                          | 0.5548                     | 0                          |
| lib/skunk/cli/application.rb                        | 139.2                      | 1.392                      | 3                          | 0.46399999999999997        | 0                          |
| lib/skunk/cli/command_factory.rb                    | 97.6                       | 0.976                      | 2                          | 0.488                      | 0                          |
| test/test_helper.rb                                 | 75.2                       | 0.752                      | 2                          | 0.376                      | 0                          |
| lib/skunk/rubycritic/analysed_module.rb             | 48.12                      | 1.7184                     | 2                          | 0.8592                     | 72.72727272727273          |
| test/lib/skunk/cli/commands/status_reporter_test.rb | 45.6                       | 0.456                      | 1                          | 0.456                      | 0                          |
| lib/skunk/cli/commands/base.rb                      | 29.52                      | 0.2952                     | 3                          | 0.0984                     | 0                          |
| lib/skunk/cli/commands/status_reporter.rb           | 8.0                        | 7.9956                     | 3                          | 2.6652                     | 100.0                      |
| test/lib/skunk/rubycritic/analysed_module_test.rb   | 2.63                       | 2.6312                     | 2                          | 1.3156                     | 100.0                      |
| lib/skunk.rb                                        | 0.0                        | 0.0                        | 2                          | 0.0                        | 0                          |
| lib/skunk/cli/options.rb                            | 0.0                        | 0.0                        | 2                          | 0.0                        | 0                          |
| lib/skunk/version.rb                                | 0.0                        | 0.0                        | 2                          | 0.0                        | 0                          |
| lib/skunk/cli/commands/help.rb                      | 0.0                        | 0.0                        | 2                          | 0.0                        | 0                          |
+-----------------------------------------------------+----------------------------+----------------------------+----------------------------+----------------------------+----------------------------+
StinkScore Total: 612.31
Modules Analysed: 13
StinkScore Average: 0.47100769230769230769230769231e2
Worst StinkScore: 166.44 (lib/skunk/cli/commands/default.rb)

「どうやらこのSkunkはRubyCritic(ウォッチ20180223)っていうgemの拡張として作られたみたい☺️↓」「skunkっていう名前が気に入ってエイヤで作ったんじゃないかな〜😆」「😆」「よくskunkっていう名前のgem名取れたなって」「ホントだ😳」「名前の奪い合いとかありますし😆」「自分だったらとりあえずリポジトリ取っちゃうかな😆」「最近だと使ってないリポジトリは譲渡しなさいって迫られたりするみたいですけど😆」


同リポジトリより

参考: RubyCritic + CircleCI + Slack でプロジェクトの Ruby コードを継続的に採点しよう | Engineer's Base Camp

「gemの名前としてstinkとかskunkとかを使うのはまだわかりますけど、CIでこれが走って『オマエのコードはこれだけ臭いゾ』とか出てきたらバトルになるんじゃないかと😆」「ですよね😆」「もうちょいオブラートにくるむとか😆」

「なおソフトウェアの世界だと、これみたいにコードに何らかの形で点数をつけるツールというのは昔からいっぱいあります」「ふむふむ」「上で言うとchurnとかcostみたいな項目はたぶん昔からあって、そういう値を元にstink_scoreとやらを算出するとかそういう感じかなと☺️」「Code Climate↓も似たようなことをやっていますね」「カバレッジみたいなメジャーな項目については算出方法が確立しているんですけど、項目をずらりと出しただけだとわかりにくくて、知りたいのは『要するに何点なの?』というところなので、このgemとかCode Climateとかはそういうところをやってくれます☺️」


codeclimate.comより

技術的負債を調査する10のポイント(翻訳)

RailsガイドProプランのお試しでクレカが不要に


同記事より


つっつきボイス:「最近始まったRailsガイドProプランは、横断検索がかなりいい感じらしいのでRailsを書き始めて間もない人には結構いいんじゃないかと思います👍」「ほほぉ😋」「本家のRails Guidesにもない機能です」「新しい人が開発中に詰まったときに簡単に調べられるのは便利でしょうね☺️: 自分は脳内にマップできてるのでたぶん使わないけど😆」「Proプランでは例のAlgolia↓でインクリメンタル検索やってるそうです」

Rails: 高速リアルタイム検索API「algolia-search-rails」gem README(翻訳)

activestorage-resumable: レジューム機能をサポート(RubyFlowより)

<!-- 同リポジトリより -->
<%= form.file_field :attachments, multiple: true, resumable_upload: true %>

つっつきボイス:「おぉ?Active Storageでレジューム機能?」「しかもアップロードで?」「レジュームは、アップロード中に回線切れても後で再開する機能ということですね」「まだ★2つ(その後14★に)ですが刺さりました?」

「そもそもHTTPの仕様ではPOSTアップロード中にレジュームできるのか?🤔」「アップロードのレジュームって難しそうですね☺️」「ダウンロードはレジュームできるんでしょうか?」「昔からありますね🧐」「Stackoverflow↓を見た感じではやっぱりアップロードのレジュームはなさそう😇」

参考: Standard method for HTTP partial upload, resume upload - Stack Overflow

「resumable gemのREADMEをざっと見ると、chunk単位でアップロードしてプログレスをLocalStorageに保存することでやってるみたいっすよ😎」「あぁ、そのレベルから頑張ってるのか😆」「これはがんばり屋さんだな〜😆」「LocalStorageって20MBぐらいしか入らないんだっけ?」「プログレス情報だけなら問題なさそう😋」

HTML5のLocal Storageを使ってはいけない(翻訳)

「ちなみにchunkという言葉はコンピューターネットワークの世界でよく使われます」「辞書を見ると『厚切りの一切れ』みたいな感じ」「HTTPの仕様レベルではアップロードのレジューム機能は提供されていないはずなので、このgemはそういうchunk単位で小分けにしたファイルを何回もアップロードすることでレジュームを実現してるということでしょうね☺️」「は〜なるほど!」「何も読んでないけどたぶんそういう実装だと思います😆」「後は使ってみないと😆」

その他Rails



前編は以上です。

おたより発掘

バックナンバー(2019年度第4四半期)

週刊Railsウォッチ(20191112後編)invisible gemで可視性を変えずにパッチ当て、スライド:「型なし言語のための型」、自然言語の言語名を推測ほか

今週の主なニュースソース

ソースの表記されていない項目は独自ルート(TwitterやはてブやRSSやruby-jp Slackなど)です。

Rails公式ニュース

Ruby Weekly

RubyFlow

160928_1638_XvIP4h


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。