- Ruby / Rails関連
週刊Railsウォッチ(20191118前編)ActiveJob引数のログ抑制、RailsガイドProプランお試し、ファイルアップロードのレジュームgemほか
こんにちは、hachi8833です。銀座Rails #15やっぱり行けばよかった😢。
銀座Rails 15で発表したスライドを公開しました。productionとかdevelopmentとかstagingみたいな環境に関するつらみみたいな話をしました: 出張!Railsウォッチ in 銀座Rails#15 https://t.co/CK9BTxbu69 #ginzarails
— Masato Mori (@morimorihoge) November 15, 2019
- 各記事冒頭には⚓でパーマリンクを置いてあります: 社内や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メッセージ出力を修正
- PR: Make AS::Deprecation.silence block thread-local by jhawthorn · Pull Request #37590 · rails/rails
# 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
- リポジトリ: ThreadLocalVar
「でも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
は以下の記事にも登場してますね。
やはりというか原田真二の「タイム・トラベル」という懐メロを思い出しました👨。
「そういえば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
(HTTPAuthorization
ヘッダーから取り出したオプションを含む)」を取ります。認証が成功したらこのブロックは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
をリファクタリング
- commit: 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_with
やends_with
に変更
- commit: Address all possible `Performance/StartWith` / `Performance/EndWith` … · rails/rails@ad76703
- PR: Fix undefined method `start_with?' for :to_json by jhawthorn · Pull Request #37708 · rails/rails
つっつきボイス:「最近も似たような修正あったような🤔」「こういうふうに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_json
でstart_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
たぶんこちらも関係してそうです↓。
⚓ポリモーフィック関連付けで:polymorphic
、:as
、 :foreign_type
をvalid_options
に追加した
- commit: `:polymorphic`, `:as`, and `:foreign_type` are valid for polymorphic … · rails/rails@2c008d9
# 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
を管理できる。各Role
がdb_config
を持つ。
これによりpublic APIの改変を回避し、ハンドラやロールの概念を扱えるようにし、各クラスのハンドラごとに複数のコネクションを内部で確立するのに必要なものを達成する。
同PRより大意
⚓Rails
⚓RSpec 3.9がリリース
RSpec 3.9のリリースノート。今後はrspec-railsだけRSpec本体とバージョンが同期しなくなるそうです。RSpec本体と足並みを揃えるより、Railsにあわせてどんどんバージョンアップしていくのが目的みたい。
また、RSpec 3.9自体は大きな文法の変更等はなさそうです。https://t.co/swYsHsTVsl— Junichi Ito (伊藤淳一) (@jnchito) October 17, 2019
つっつきボイス:「いつの間にか3.9になってた😳」「rspec-railsだけ本体とバージョンが合わなくなる?」「rspec-railsは足並み揃えるよりどんどん改修入れる方を優先しようということですね☺️」
なお、私が今転生作業中のオレオレRailsアプリはこっそりminitestにしてます😆。
⚓HerokuがSorbetをやってみてわかったこと(Ruby Weeklyより)
- 元記事: Static Typing in Ruby with a Side of Sorbet | Heroku
- リポジトリ: chanzuckerberg/sorbet-rails: A set of tools to make the Sorbet typechecker work with Ruby on Rails seamlessly.
よかった点:
- 結果を保存せずに同じメソッドを2回呼んでいたのを指摘
- nullableなカラムを公開してたのを指摘
- 雑に
nil
またはtrue
を返していたのを指摘
つっつきボイス:「HerokuがSorbetを使ってみたと」「4人チームで実験的にやってみた段階だそうですが、上のような点を見つけてくれたそうです😆」
「Sorbetはウォッチでも何度か取り上げましたが、RailsというよりRubyやってる人たちの間でアツい静的型チェッカーです😆」「😆」「Railsアプリを普通に分にはSorbetまだ知らなくても大丈夫かなと思いますが😆、とてもミッションクリティカルなアプリを書くときには必要になるかもしれませんね☺️」
「とりあえずアイスクリームアイコン🍨↓がかわいい❤️」
「sorbet-rails試してみたかったんですが、なぜか今日のbundle install
がえらく遅くて、しかも今見たらnot publicly available yetとか出てた😇」「😆」
その後うなすけさんの以下のスライドに今頃気づきました。
- スライドPDF: Sorbet撤退記
⚓Basecampが無料個人版をリリース
つっつきボイス:「Basecampが個人版を?へぇ〜」「法人版だと価格的に見合わないので出したそうです」「completely freeって書いてますね」「マジで?」「見落としてた😅」「機能制限はあるけど無料!」「ストレージ1GBか〜😅」「個人なら十分かも」
「一応背景を説明すると、BasecampというのはRuby on Railsフレームワークの作者であるDHH(David Heinemeier Hanson)↓がいる会社で、一種のプロジェクト管理ツール的なサービスであるBasecampはもちろんRailsで提供しています」「日本ではあまり知られていませんけど😆」「日本だと(聞き取れず)が使ってるらしいけどネ」
"At Basecamp.. nothing important should happen in chat. Anything that’s really important that requires serious deliberations and major decisions and major point of information should be in a format where someone can catch up on their own time" https://t.co/ZibdUMISHc
— DHH (@dhh) November 16, 2019
「Basecampのサービスを何に例えたらいいかな🤔」「GitHubプロジェクトからソースコード管理を引いたような感じですかね〜☺️」「タスク管理とかチャットとかスケジュールとか」
「そしてBasecampに新しい機能が入ると、いずれその機能がRailsにも入ってくるということが割とあったりします😆」「へぇ〜」「たとえばRailsのAction CableはRails 4.xで入ったんですけど、それはBasecampにチャット機能が入ったからだろう、なんてことがよく言われます🤣」「😆」「Basecampを見てれば直近の未来がわかるかもしれないと」「BasecampはフルにRailsで書かれているはずなので知っておくといいと思います☺️」
参考: Action Cable の概要 - Rails ガイド
⚓Skunk: 「コードの臭い」を数値化(Ruby Weeklyより)
- 元記事: Introducing Skunk: Combine Code Quality and Coverage to Calculate a Stink Score - Ruby on Rails Upgrades
- リポジトリ: fastruby/skunk: A StinkScore Calculator for Ruby Code
つっつきボイス:「コードがどのぐらい臭ってるかを数値化する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とかはそういうところをやってくれます☺️」
⚓RailsガイドProプランのお試しでクレカが不要に
つっつきボイス:「最近始まったRailsガイドProプランは、横断検索がかなりいい感じらしいのでRailsを書き始めて間もない人には結構いいんじゃないかと思います👍」「ほほぉ😋」「本家のRails Guidesにもない機能です」「新しい人が開発中に詰まったときに簡単に調べられるのは便利でしょうね☺️: 自分は脳内にマップできてるのでたぶん使わないけど😆」「Proプランでは例のAlgolia↓でインクリメンタル検索やってるそうです」
⚓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ぐらいしか入らないんだっけ?」「プログレス情報だけなら問題なさそう😋」
「ちなみにchunkという言葉はコンピューターネットワークの世界でよく使われます」「辞書を見ると『厚切りの一切れ』みたいな感じ」「HTTPの仕様レベルではアップロードのレジューム機能は提供されていないはずなので、このgemはそういうchunk単位で小分けにしたファイルを何回もアップロードすることでレジュームを実現してるということでしょうね☺️」「は〜なるほど!」「何も読んでないけどたぶんそういう実装だと思います😆」「後は使ってみないと😆」
⚓その他Rails
この記事、実はQiitaを使い始めたその日に書いた、僕の最古の記事のひとつなんだけど、僕の記憶力が悪すぎていまだに覚えきれないので、折に触れてチェックしてます。(で、今日も読んでたw)
noticeやalertの設定方法の違い https://t.co/dzgvuB1AEb #Qiita
— Junichi Ito (伊藤淳一) (@jnchito) November 12, 2019
できますよ。というか、同様の内容のぷるりをいただいたもの取り込んだので、今はこんな感じで動いているはずです。 https://t.co/9sITP265S8
— Akira Matsuda (@a_matsuda) November 12, 2019
前編は以上です。
おたより発掘
ソルベのアイコンはもちょの顔文字 (o・∇・o)
— さく (@sakuro) November 20, 2019
バックナンバー(2019年度第4四半期)
週刊Railsウォッチ(20191112後編)invisible gemで可視性を変えずにパッチ当て、スライド:「型なし言語のための型」、自然言語の言語名を推測ほか
- 20191111前編 Active Recordモデルをprivateで封じ込める、心折れないRailsスキーマ管理、Railsセッションをクロスドメイン共有ほか
- 20191106後編 holiday_japan gemで日本の祝日判定、小さい関数が有害になるとき、Gitブランチのファジー検索ほか
- 20191105前編 Rails 6のデフォルト設定解説、DHHも消したいaccepts_nested_attributes_for、スライド『実践Railsアプリケーション設計』ほか
- 20191029後編 Ruby 2.7.0-preview2、tapping_device gemとhumanize gem、平成Ruby会議ほか
- 20191028前編 RailsにSTI用メソッドsti_class_forとpolymorphic_class_forが追加、RuboCopを変更箇所だけにかけるgem、strftime書式生成サイトほか
- 20191021 Rails 6でhas_many関連の修正やSprockets 4.0対応、Shrine 3.0がリリース、Minitestスタイルガイドほか
- 20191015 スライド「Rails Performance issues and Solutions」を見る、dirtyに*_previously_was が追加、Sidekiq 6.0.1ほか
- 20191008後編 Ruby 2.7のInteger#[]でバイナリチェック、rubyzip gemは強力、13KBのJavaScriptゲームほか
- 20191001後編 RedisとRubyをつなぐredis-object gem、Fullstaq Rubyの新バージョン、COUNT(*)とCOUNT(1)の速度ほか
今週の主なニュースソース
ソースの表記されていない項目は独自ルート(TwitterやはてブやRSSやruby-jp Slackなど)です。