こんにちは、hachi8833です。Pixel 3がちょい気になっています。
- 各記事冒頭には⚓でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ
- 「つっつきボイス」はRailsウォッチ公開前ドラフトを社内有志でつっついたときの会話です👄
つっつきボイス:「お、Pixel 3か、値段の割にストレージが少ないんですよね📱: 今の自分のiPhoneも、いつか見るつもりのNetFlix動画やら音楽やらであっというまにストレージ埋まっちゃうし」「私はWikipedia(日と英)がまるっと入ればいいかな...」「Pixelを見てると、ちゃんとしたスマホを作れば結局このぐらいの値段になるよなって思いますね😎」
⚓Rails: 先週の改修(Rails公式ニュースより)
⚓名前付きスコープに委譲するメソッドを定義のタイミングで生成
名前付きスコープへ委譲するメソッドは、リレーションで
method_missing
が呼び出されるときに定義される。
名前付きスコープ内のレシーバは#29301以降、一貫性のためdefault_scope
などと同様にリレーションに変更されている。
大半の名前付きスコープはmethod_missing
でリレーションから委譲される。というのも、Relation
のインスタンスメソッドと競合しないよう#31179でスコープの定義を許さなくなったため。しかし、名前付きスコープと同じ名前のメソッドがスーパークラス(Kernel.open
とか)のいずれかのメソッドで定義されていると、リレーションのmethod_missing
が呼び出されていなかった。
問題修正のため、名前付きスコープに委譲するメソッドは定義時に生成されるようにする。
同PRより大意
# activerecord/lib/active_record/relation/delegation.rb#L34
+ protected
+ def include_relation_methods(delegate)
+ superclass.include_relation_methods(delegate) unless base_class?
+ delegate.include generated_relation_methods
+ end
+ private
+ def generated_relation_methods
+ @generated_relation_methods ||= Module.new.tap do |mod|
+ mod_name = "GeneratedRelationMethods"
+ const_set mod_name, mod
+ private_constant mod_name
+ end
+ end
+ def generate_relation_method(method)
+ if /\A[a-zA-Z_]\w*[!?]?\z/.match?(method)
+ generated_relation_methods.module_eval <<-RUBY, __FILE__, __LINE__ + 1
+ def #{method}(*args, &block)
+ scoping { klass.#{method}(*args, &block) }
+ end
+ RUBY
+ else
+ generated_relation_methods.send(:define_method, method) do |*args, &block|
+ scoping { klass.public_send(method, *args, &block) }
+ end
+ end
+ end
+ end
+ end
つっつきボイス:「generated_relation_methods
で@generated_relation_methods ||= Module.new.tap
でメモ化してから定数をprivateにして渡している」「generated_relation_methods.send(:define_method, method)
でdefine_method
を使って定義してるんですね」「難しい...」
参考: instance method Module#define_method
(Ruby 2.5.0)
参考: instance method Module#private_constant
(Ruby 2.5.0)
⚓関連付けの再読み込み時にQueryCacheをクリアすることで振る舞いを一貫させた
# 「Post --has_many--> comments」「Post --has_one/belongs_to--> author」が前提
# この場合QueryCacheがクリアされ、レコードが読み込まれる
post.reload
# この場合QueryCacheの外でクエリが実行されることでレコードが読み込まれるが
# QueryCacheはクリアされない
post.reload_author
# この場合レコードは読み込まれず、QueryCacheもクリアされない
post.comments.reload
つっつきボイス:「現状が上↑のようになってると」「関連付けがある場合とそうでない場合でのキャッシュのクリア方法を揃えたってことね☺️」「バグではなさそう?」「バグではないと思うけど元の挙動がわかりにくいしバグの温床になりやすいからでしょうね😎: で、以下のように↓キャッシュのクリアを一貫させるようになったと」
# 以下はいずれもキャッシュをクリアするようになった
post.reload_category
post.reload_author
post.comments.reload
「キャッシュはだいたい難しいですね: 細かく制御しようとするとよくバグるので🕷」
⚓skip-webpack-install
オプションを追加
# railties/lib/rails/generators/testing/behaviour.rb#L67
def run_generator(args = default_arguments, config = {})
capture(:stdout) do
args += ["--skip-bundle"] unless args.include? "--dev"
args |= ["--skip-bootsnap"] unless args.include? "--no-skip-bootsnap"
- args |= ["--skip-javascript"] unless args.include? "--no-skip-javascript"
+ args |= ["--skip-webpack-install"] unless args.include? "--no-skip-webpack-install"
generator_class.start(args, config.reverse_merge(destination_root: destination_root))
end
end
つっつきボイス:「お、今まではスキップできなかった?」「今までは--skip-javascript
だったのが削除されて--skip-webpack-install
に変わったみたいです」「なるほど: skip-javascript
だとJavaScriptを全部無効にするみたいに見えてよくないという考え方もあるし🤔」「Webpackerのインストールが重いから外せるようにしたとか?」「むしろNode.jsなどのJSエンジンが入ってないとrails new
に失敗するから、それを回避するためかも: --skip-webpack-install
すればJSエンジンがなくても動くんじゃないかな?と予想してみる」
⚓db:migrate:status
をDatabaseTasks
に引っ越し
# activerecord/lib/active_record/railties/databases.rake#L150
desc "Display status of migrations"
task status: :load_config do
- unless ActiveRecord::SchemaMigration.table_exists?
- abort "Schema migrations table does not exist yet."
- end
- # output
- puts "\ndatabase: #{ActiveRecord::Base.connection_config[:database]}\n\n"
- puts "#{'Status'.center(8)} #{'Migration ID'.ljust(14)} Migration Name"
- puts "-" * 50
- ActiveRecord::Base.connection.migration_context.migrations_status.each do |status, version, name|
- puts "#{status.center(8)} #{version.ljust(14)} #{name}"
- end
- puts
+ ActiveRecord::Tasks::DatabaseTasks.migrate_status
end
end
つっつきボイス:「単なる移動にしては、コメントを見るとやけに喜ばれてますね」「『Nice refactor! 👏』とか😊」「気になってたけど後回しにしてた箇所をリファクタリングしてくれてありがとう!みたいな感じかな: お、今までなかったテストも追加されているし: コードの移動だけでこのテストが増えるはずはないから」「あー、移動前はrakeタスクだったからテストがやりにくかったんだ!」「あー、それで喜ばれたのか😃」「移動のついでにカバレッジも増やしてくれたから」
「rakeタスクのテストってかなりやりづらいし、タスクをrunするのも遅いし、rakeのテスト書きたくない😆」「ほんにそうですね😣」
『Nice refactor! 👏』でこれを思い出してしまいました↓。
モブプログラミングもボディビル大会みたいな声掛けを色々考えればより盛り上がるのでは?
「ナイス変数名!」
「テストがオールグリーン!」
「コミットログがキレイ!」— :craftsman/kawasima (@kawasima) August 10, 2018
⚓ActiveRecordにconnects_to
とconnected_to
を実装
モデルで複数のデータベースに接続する機能と、それらをブロックで切り替える機能を実装したそうです。
class AnimalsBase < ApplicationRecord
connects_to database: { writing: :animals, reading: :animals_replica }
end
ModelInPrimary.connected_to(database: { slow_readonly: :primary_replica_slow }) do
ModelInPrimary.do_something_thats_slow
end
つっつきボイス:「レプリカを参照できるようになった!」「あーなるほど、上のconnected_to
は、たとえばこのブロックの中でだけデータベースを切り替えたいときに使うのか😍」「どんな場合でしょう?」「確かにこういうのやりたいことある: たとえばものすごく重いデータベースクエリ(集計クエリとか)を管理画面から出力したいとすると、通常のDBにそういう重いクエリを投げてしまうとフロントまで重くなってしまうんだけど、そういうクエリだけ別の集計用レプリカDBに投げる、なんてことができる」「お〜」「その処理自体は大したコードじゃなくて、その場でちょろっとできればいいのに、これまではそのためにdatabase.ymlを書き換えないといけなかった: でもこれなら不要になるし」「お〜😃」
「DHHの#33877の続きみたい」「その#33877の話を見ると、まさに先週のウォッチで話したマルチDBがらみそのものですね: やっぱりこのあたりはまだまだ変わる可能性ありそう😆」「そういえばプルリクのコメントもめちゃ伸びてますね」
⚓テンプレートやパーシャルのアロケーション情報を表示
- PR: Add allocations to template renderer subscription by eileencodes · Pull Request #34136 · rails/rails
変更前:
Rendering posts/new.html.erb within layouts/application
Rendered posts/_form.html.erb (9.7ms)
Rendered posts/new.html.erb within layouts/application (10.9ms)
Completed 200 OK in 902ms (Views: 890.8ms | ActiveRecord: 0.8ms)
変更後:
Rendering posts/new.html.erb within layouts/application
Rendered posts/_form.html.erb (Duration: 7.1ms | Allocations: 6004)
Rendered posts/new.html.erb within layouts/application (Duration: 8.3ms | Allocations: 6654)
Completed 200 OK in 858ms (Views: 848.4ms | ActiveRecord: 0.4ms | Allocations: 1539564)
つっつきボイス:「コンソールの項目が1個増えてAllocations: 6004
みたいに表示されるそうです」「ロガーで出てくるヤツ」「このアロケーションってメモリということでいいんでしょうか?」「単位がわからんけどpayloadと書いてあるし、たぶん普通にメモリのバイト数だと思うけどな〜🤔」「ともあれこういう情報が出てくれるとアプリが遅くなったときの原因特定がやりやすくなりますね❤️: アプリのビューがでかすぎてパフォーマンスが落ちたときとか」
⚓Rails
⚓無名コントローラでconcernsをテストする(RubyFlowより)
つっつきボイス:「とてもあっさりした記事ですが」「モジュール名にあるRescuerって英語的にありなんだろか?😆」「造語っぽい響き...と思ったら辞書にあった💦」「モジュールだから-er
で終わらせたかったんだろうなきっと🤓」
「この記事みたいな書き方、確かあったはず🤔」「うん、ポイントはRSpecの中でこうやって一時的にコントローラを作れること↓: その中でモジュールをインクルードしておいてそのコントローラをテストする」
# 同記事より
describe BillingErrorRescuer, type: :controller do
controller do
include BillingErrorRescuer
def action
@account = FactoryBot.create :account
raise Billing::LimitExceeded
end
end
# 略
end
「元々は記事にあるBillingErrorRescuer
モジュールをテストしたいんだけど、モジュールは直接テストできないのでインクルード用に何かダミーのコントローラが欲しい、でもそのコントローラはproductionでは使わないので本編のコードには置きたくない、ていうときにこれを使うんじゃないかな」「なるほど!」「このcontroller
ってメソッド、ちゃんとRSpecに生えてるみたいですね: 元々RSpecにあるのかな?🤔」「おー、あったあった↓🎯」「確かにこういうのはRSpecにないとできないヤツ: controller(ApplicationControllerSubclass)
みたいに引数も渡せると」
参考: anonymous controller - Controller specs - RSpec Rails - RSpec - Relish
# relishapp.comより
require "rails_helper"
class ApplicationController < ActionController::Base
class AccessDenied < StandardError; end
end
class ApplicationControllerSubclass < ApplicationController
rescue_from ApplicationController::AccessDenied, :with => :access_denied
private
def access_denied
redirect_to "/401.html"
end
end
RSpec.describe ApplicationControllerSubclass do
controller(ApplicationControllerSubclass) do
def index
raise ApplicationController::AccessDenied
end
end
describe "handling AccessDenied exceptions" do
it "redirects to the /401.html page" do
get :index
expect(response).to redirect_to("/401.html")
end
end
end
「これならモジュールの単体テストがキレイに書けるので、当然これ使う方がいいですね😋: なおこのモジュールは本来はconcernとしてコントローラで使います」
⚓render_async 2.0がリリース(RubyFlowより)
- リポジトリ: renderedtext/render_async
関連記事を昨年翻訳したrender_asyncの2.0では、jQueryが素のJavaScriptに変更され、IEでのエラーハンドリングやイベント発火などに対応したそうです。
つっつきボイス:「お、2.0になってjQueryじゃなくなったし👍」「ちなみにrender_asyncがやってることは全然大したことなくて😆、以下のようにerbでrender_async
書くとAjaxをロードしてdocument.write
とかができるようになる」「へぇ〜」「古いIEの対応も向上したようです」「render_asyncは、ものすごくアクセスの多いサイトなんかでは効果的だと思います😊: 某漫画サイトとかなら使いたいやつでしょうね😆」「😆」
<-- 同リポジトリより -->
<%= render_async comment_stats_path %>
⚓Screencast: Twilio APIのService Object
- Screencast: Service Objects for API Interactions with Twilio | Drifting Ruby
- リポジトリ: driftingruby/154-service-objects-for-api-interactions-with-twilio
- サイト: Twilio - Communication APIs for SMS, Voice, Video and Authentication
Service Objectの話題にと思って取り上げましたが、つっつきは予想を超えてTwilioの話になりました😊。
つっつきボイス:「Twilioは、SMS(ショートメッセージサービス)とかと電話を連携させたりするAPIサービスで、かなり前から有名ですね☎: 確かテキストをXMLで放り込むと音声を再生できるんじゃなかったかな(Programmable Voice)」「知らなかった〜」
「これも確かXMLで設定を投げると、電話の音声案内によくある『〜の場合は1、〜の場合は2を押してください』みたいなのをやってくれたと思う」 「ふむふむ」「サポセン構築を支えるサービスでもあるんですね」「Twilioは日本法人もあるはずで、(ググると)そうそう、KDDI↓」「確かに電話会社ならやりたいAPIサービスでしょうね」「よくあるSMS認証なんかもこれでさっとやれる: サイトで電話番号を入力するとそこに自動でSMSが送信されるヤツですね」「お〜」「SMS認証サービスは他にもいろんな会社もやってますが、Twilioは随分前からやってる」
参考: 企業が「SMS認証」を導入するワケ!? | SMS送信サービス 「空電プッシュ」
「お、Faxサービスもある😆」「やっぱ日本に進出するにはFaxもサポートしないとあかんのでしょうね🤣」「未だにFax使ってるなんてもう日本ぐらい🤣」
「そういえばAWSのアカウント作成にもSMS認証使われてますね: アカウントを作ると電話がかかってきて、キーを音声で知らせてくる」「そういえばそう!」「そういうのも含めた文字の音声化や音声の文字化もやれる💪」
「Twilioは老舗なんで、その分APIも割と古い感じだった覚えがあります(今はわかりませんが)」「XML使うあたりがそんな感じですね: 今ならJSONとかYAMLでやりたいでしょうし」「TwilioはWebRTCと連携したり、あと確かSIPサーバーと直結させることもできたりとか、実は割と高機能」「確かに〜」
参考: WebRTC - Wikipedia
参考: SIPサーバ(SIP server)とは - IT用語辞典
「Twilioは日本のバックエンドがKDDIなんで、たぶんめったなことでは落ちないだろうという期待もできるし😎」「ちなみにもしこういう上位のTierで障害が起きたらたぶん日本のインターネットのかなりの部分に影響する💀」「ひょえ~」「Tier 1かどうかはどの地域から見るかで違ってくるところもあるので一概には言いにくいですが、日本のTier 1というとIIJ、Wikipediaを見るとNTTコミュニケーションズがアジア地域でTier 1: お、Tier 1のSprintもソフバン傘下になっているからTier 1か」「それにしてもさっきから障害関連の情報ってなぜかググってもうまく出てこないし...」「もしかして検索結果に出にくくなってるとか😆」
参考: ソフトバンクが最上位インターネットプロバイダ「Tier 1」に:Geekなぺーじ
参考: ティア1 - Wikipedia
Wikipediaより(CC BY-SA 3.0)
そういえば子どもの頃読んだ科学読み物で、モナリザの体格や身長から声を推測してモナリザの声をコンピュータで再現するという記事を見たことがあります。当時はまだ大型コンピュータやミニコンの時代だったので大変だったと思います。以下はもっと新しいもののようです。
⚓Active Storageの添付ファイルを削除する(RubyFlowより)
つっつきボイス:「このCodemy.netっていうサイト、意外にscreencastが盛りだくさんですね」「動画の下に解説部分があるからすぐ見えるのがいいな: リスト部分はもっと狭くていいんだけど😆」
# 同screencastより
class Post < ApplicationRecord
# ...
# add :remove_cover_picture to attr_accessor
attr_accessor :state_event, :remove_cover_picture
# add purge_cover_picture callback
after_save :purge_cover_picture, if: :remove_cover_picture
private def purge_cover_picture
cover_picture.purge_later
end
# ...
end
「へー、Active Storageにpurge
ってメソッドあるんだ↑」「そこは自分で実装するんですね😆: carrierwaveならremove_なんちゃら
って付ければそう判定してくれるところだけど、そういうのじゃないのか😆」「Active Storageはそこまではやらなさそう」「まあやんなくてもいい気はします🤣」
参考: ActiveStorage::Attached::Many -- purge
「removeといえば、carrierwaveだと確かサイズを引数で指定して、そのサイズ以上だったら消すってのができますね」「バージョンとかも引数に渡せたと思います」「Active Storageでもそのうちできるようになるんじゃないかな?なんて」
「ちなみにバージョンを指定して添付ファイルを消したいというのは割と需要がありますね: carrierwaveでバージョン指定することでオリジナルは消さずにサムネイルだけ一括で消すとかしといて、後は新規アクセスでサムネイルが再生成されるようになってればおkみたな」「ソース見てみっか」
「...く、最近Macbookが不調でなかなかIntelliJ IDEAが起動しない〜😅」「そういえば私の古いMacbookをこの間Mojaveにアップグレードしたら↓、Chromeのレインボーカーソルくるくるがピタッと止みました」「自分のMacbook、まだHigh SierraですらないSierraだからな〜、不調の原因それかもしれない...」
「でActive Storageのpurge
メソッドは、と...お、Attached::One
なんてクラスが😆」「ワン?!」「そういえばActive StorageのAttached::One
ってhas_manyっぽく書けますよね?」「てことはMany
もあるってことか: あった🎯」「こいつらはActiveSupport::Autoload
で動いてないから、各自好きにロードして使ってくれってことなんでしょうね」
参考: ActiveStorage::Attached::One < ActiveStorage::Attached
参考: ActiveSupport::Autoload
「で、これか↓」「purge
には引数がないのでActive Storageでは特定のバージョンだけ削除とかはできないということがこれでわかった🧐」「detach
ってのあるんですね」「attach
にdetach
とあるけどpurge
は実際にファイルを消すところまでやるっぽい」「detach
はpurgeまではしないとあるからデータベースから消すだけで、ファイルが残ると」「purge
はデータベースもファイルも消すと」「これは知らないと間違えるヤツ😆」「detach
したけど残ってましたみたいな😆」「両方並んでればdetach
の方が弱そうというのは想像つきますけど」
#5-2-stable/activestorage/lib/active_storage/attached/one.rb#L47
# Deletes the attachment without purging it, leaving its blob in place.
def detach
if attached?
attachment.destroy
write_attachment nil
end
end
# Directly purges the attachment (i.e. destroys the blob and
# attachment and deletes the file on the service).
def purge
if attached?
attachment.purge
write_attachment nil
end
end
# Purges the attachment through the queuing system.
def purge_later
if attached?
attachment.purge_later
end
end
「バージョン指定云々はたぶんBasecampで使われてないだけな気がするから、そのうちサポートされるかもね😊」
⚓Railsアプリで実際に起きたセキュリティ問題5つ(RubyFlowより)
つっつきボイス:「実は既に翻訳許可取って、翻訳だけは終わってる状態なので近々公開します😃」
「1.のセッション期限って、Railsがサポートしてなかったっけ?」「期限がものすごく未来の時間に設定されるやつですよね」「Devise使ってるとtimeoutable
って指定が使えると」
# 同記事より
class User < ActiveRecord::Base
devise :timeoutable
end
「お、Rails 5.2ではセッションcookieに期限が含まれるようになってるって記事に追記がある(翻訳したときはなかった)」「そういえば以前のTechRachoで5.2の署名済みcookieが非互換になった云々の話があった気がするけどそれじゃないですか?」「あったかもそういえば」「ともあれ5.2ならひとまず対応済みってことね😊」
↓5.2アップグレードガイドの更新情報に含まれているのを見つけました。
参考: Rails アップグレードガイド | Rails ガイド
セキュリティ向上のため、Railsでは暗号化または署名付きcookieに有効期限情報を埋め込むようになりました。
有効期限情報が付与されたcookieは、Rails 5.1 以前のバージョンとの互換性はありません。
Rails 5.1 以前で新しいcookieを読み込みたい場合、もしくは Rails 5.2 でうまくデプロイできるか確認したい場合は (必要に応じてロールバックできるようにしたい場合は) Rails.application.config の action_dispatch.use_authenticated_cookie_encryption を false に設定してください。
同ガイドより
「2.は何回間違えたらアカウントをロックするか」
「3.は、入力したユーザー名やパスワードが間違ってたときに『そのユーザーは登録されてません』とか『パスワードが間違ってます』みたいな親切すぎるメッセージを出すと、むしろ攻撃の手がかりになっちゃうというヤツですね」「バリデーションで余計な情報は出すべきでないという話: ただね、サービスの種類によっては親切に出してあげないと問い合わせが大量に押し寄せるので、ポリシーをどうするかは頭の痛い問題」「具体的にはどんな感じでしょう?」
「『パスワードの再設定』フォームなんかがそうなんですが、再設定のために入力したメールアドレスが登録済みなので送信しましたというメッセージを出してしまうと、登録してない第三者でもそのメールアドレスが登録されているかどうかがわかっちゃう: ネットには流出したメールアドレスとパスワードのリストを売ってるダークなサイトがいろいろあるんで、それを元に攻撃者が『こいつはいない、こいつはいる』と試していけば存在するユーザー名のリストを作れる: なのでメールアドレスが登録済みかどうかをうかつに表示すると防衛力が落ちるという話」「お〜」
「その意味ではそういう情報を表示しないほうがセキュアなんですが、表示しないと今度は『このメールアドレスは登録されてないって言われちゃったんですけど』みたいな問い合わせが山のようにやってくるという😅: リテラシーの高い人にはわかってもらえるんですけど、世の中そういう人ばかりではないので」「こういうのってメッセージの文面の書き方ひとつで問い合わせが目に見えて増えたり減ったりしますよね☺️」
⚓Rails初心者とバレる書き方
「4.の権限昇格のコード例にあるこの書き方↓、ログインしないとできないはずの操作の中でこれ書いたらコードレビューで100%ツッコまれる」「そういう状況ではid
で直接find
してはいけない」「リレーションがあるならそれを使えと: 反論の余地なし」「職務質問もの👮🏼♀️」
# 同記事より
Project.find(params[:id]) # あかん書き方
current_user.projects.find(params[:id]) # たとえばこんなふうに書くべき
「もっと言うと、たとえstrong parametersとかも正しく書かれていて、設計も十分吟味されているとしても、current_user.projects.find(params[:id])
のように書くべき」「そう!ホントそう!」
「コード例の上と下ではコードが放つ臭いも違ってくるし: 下はどこから取ってきているのかが明らかだけど、上はもしかするとそのユーザー以外のところから取ってきているかもしれないから」
「テストを書くときにも、下は現在のユーザーについてテストを書けばいいけど、上はそれ以外のところから取ってきた場合についてもすべてテストを書かないと網羅できないし」
「上の書き方は基本的にデメリットしかないと思う😡」「同意!」「上はいかにも教科書に書いてありそうですよね」「アクセス制限とかないシンプルな場合なら確かに上のようになっちゃうし、IDEでデータベースを何も考えずに取りに行くと上のになっちゃうんですけどね」
「あと、このあたりはURLの設計にもよるんですよね: たとえばTwitterはログインしていなくてもある程度タイムラインとかを表示できるんですが、そんなふうにログインしてもしなくても同じURLで同じように表示したいときなんかはこういう書き方になることもないわけではない」
「current_user
みたいなスコープをいちいち介さないといけないのは面倒に思えるかもしれませんし実際面倒ですが、これはやらないわけにはいかないことなので」「たった2行のコードでご飯が三杯食べられそうな話になった😋」
「上はRails初心者にとても多い書き方」「初心者を見つけるのに使えそう」「ずっと前に指摘されたことあった気もする💦」「上の書き方してたら『あ、書き慣れてないな』って即断定する😎: モデルのクソコードは読み込まないと見分けが難しいんですが、コントローラのこういう書き方とか、他にはfreeze
のし忘れとかをやってるのはコードレビューで見つけやすい」「こういう指摘は反論しようがないからレビュー戦争になる心配もないし」
「ちなみにCanCanだとaccessible_byっていうスコープが入るから、どのユーザーでも同じように書けるという謎のメリットはありますけどね: 自分はあまり好きじゃないけど」「なるほどね☺️」「あれ、Punditの方が好きかと思ってたけど?」「ん〜どっちもあんまり好きじゃない🤣: CanCanはやってることがいろいろ多すぎてちょっとウザい」「CanCanはビューにも生えてくるぐらい幅広いし: まあ必要ですけどね」「でもビューに寄りすぎるのはちょっとな〜とは思うし」
「確かにCanCanは責務がコントローラからビューまで広がっているのでちょっとつらい: Punditの方は、自分のやりたいことをやろうと思うとん〜?という気持ちになりがちではある」「自由度という意味では、Punditの方がどこまで生やすかを自分で決められるから高いですよね」「Punditは『概念モデルとしては正しい!』みたいな感じで書けるけど、頑張って設計していると結局モデルクラスを増やすしかない気がするんですよね〜: 1個のモデルクラスにいろんな可視性を持ち込むより、別のモデルを作ってそっちで生やす方がいいんじゃないかって」「ちょうど今の案件でPundit使っててつらみ理解できる😢」「Punditの方が原理主義っぽいから性に合うかと思った😆」「権限とかなくていいし🤣」
「最後の5.はweak password問題」「keypass、どっかで一度使おうとした覚えがあったけど結局1passwordにした」「1password、サブスクリプションに変わって買い切りできなくなったのが悔しいです😭」「有料だけど、もう自分も1passwordにロックインされちゃったしな〜😆」
「パスワードチェッカーって実装する側にとっては割と厄介ですよね: さっと導入できればいいけど、バリデーションで通らなかったパスワードをサーバーに投げないかどうかって意見が分かれるところだし」
「ところで、サイトによってはチェックが恐ろしく厳しいところがあるじゃないですか: 英大文字小文字と記号と数字を全部含めろぐらいならまだしも、ユーザー名と同じ並びの文字列が何文字以上あったら他がセキュアでも却下するところとか🔐」「あるある〜😅」「しかも記号や数字が固まってたらダメで、散らさないといけないとか」「あれはホントつらいし、それならパスワードを30文字にしろと言われる方がマシ😤」「あ、残り時間が🕑」「巻きで行きましょ〜」
⚓Passengerでプロセスをオーケストレーションする
つっつきボイス:「Kubernetesを使わずにKubernetesみたいなことをする?」「英語タイトルからはわかりにくいんですが、PhusionなのでPassengerの記事でした: Hongliって何だろうと思ったら中国の企業で、Phusionがそこのお手伝いをしたようです」「最初の2つの図はPassengerで、3つ目のこれ↓がオーケストレーションの概略か: お?図だけ見ると、フロントのサーバーが複数あってもそれをPassengerに集約できるってことなのかな?もしかしたらPassengerにもクラスタ的なプロダクトがあるのかも🤔」
⚓Itamae
つっつきボイス:「Itamae、最近あまり見かけてない気もするけどコミットは着実に行われてる」「chefのオルタナティブですね」「クックパッドさんのgemだから当然そこでは使ってるだろうけど」「むしろ最近serverspecを見かけない気がする: たぶんDockerが普及したから🐳」「そういえばそうかも」「serverspecを一生懸命書く時間があるなら、Dockerでアイソレーションする方が考えることが減るだろうし」
- サイト: Serverspec - Home
⚓その他Rails
The Rails upgrade took a year and a half. railsコミッターが数人いてもそうだよなぁ。 / “Upgrading GitHub from Rails 3.2 to 5.2 | GitH…” https://t.co/lv5dpj54yI
— すぎちゃん🎙🎧💻 (@koheiSG) October 10, 2018
こんなライブラリが出てくるぐらいだから、 https://t.co/8AtU89ETQo
みんな大好きNetflixでも何かしらの形でヘビーユースされてそうですよね。とかいう例を出してあげると、そういう人にも伝わるかも?— Akira Matsuda (@a_matsuda) October 11, 2018
つっつきボイス:「速さが自慢というfast_jsonapiは以前のウォッチでも取り上げましたが一応」「Netflixはオープンソースでもいろいろ公開していますね」
↓こちらはつっつきの後で見つけました。
>「Rubyは国内でしか使われてない」というデマに辟易
これどこ情報なんだろうね。
私は割と高い頻度で海外に来る(Microsoft の本社が米国🇺🇸にある)けど
海外の MS 社員の間でも Ruby 人気だよ!
「俺のイチオシは Ruby」と聞いたこと何度もあるし昨日もシアトルで言われたhttps://t.co/8Blc6cObcI— Madokaちょまど@ITエンジニア兼マンガ家 (@chomado) October 11, 2018
⚓Ruby trunkより
⚓String内部表現にUTF-8 BOMを含めるべきでない
BOM入りUTF-8が許容されているために、BOM入りCSVファイルでトラブったそうです。以下が回避方法だそうです。
# 同issueより
IO.read(mode:'r:BOM|UTF-8')
つっつきボイス:「あーBOM☺️」「BOMキライ😭: むかーしにUTF-16の納品ファイルにBOMありのとBOMなしのとあってスクリプトで外したりしないといけなかったことがありました」「そういうのこそCIでチェックすべき🧐」「CSVでBOM踏んだことあったナ😤」「エンジニアなら一度はBOMを踏むし😆」
「Wikipedia見ると、UTF-8の場合BOMは本来不要だし必須ですらないのに、あっても許容されているそうです😢」「そうそう、たまにわざわざ付けちゃう人いるんですよね」「みんな、UTF-8にBOM要らないからね〜!」
⚓リクエスト: Net::HTTP
でHTTPSのSNIにserver_name
が欲しい
つっつきボイス:「あー、HTTPS接続のときはSNIで使うserver_name
が欲しいってことか: そういえばRubyコアライブラリのNet::HTTP
っていつの間にかHTTPS対応してますね」
参考: Server Name Indication - Wikipedia
⚓Ruby
⚓HTTParty gemでログを出力する方法
# 同記事より
def GoogleGateway
include HTTParty
logger Rails.logger, :info, :apache
...
end
つっつきボイス:「HTTPartyは割と有名なRuby製HTTPクライアントソフトウェア: faradayなんかと並ぶ」「もっと好きなHTTPクライアントがあるって以前おっしゃってましたが何でしたっけ?」「自分が好きなのはhttpclient❤️」「そうでした: 以前のウォッチで話が出てた」
- リポジトリ: lostisland/faraday
- リポジトリ: nahi/httpclient
httpclientは重要な情報がREADMEではなくドキュメントにあるんだそうです。
⚓Rubyのメソッドでdestructureする
# 同記事より
destructure def adds(a: 1, b: 2)
a + b
end
adds(a: 1, b: 2)
# => 3
adds(OpenStruct.new(a: 1, b: 2))
# => 3
Foo = Struct.new(:a, :b)
adds(Foo.new(1,2))
# => 3
つっつきボイス:「Rubyって無茶して遊ぶ人がいろいろいるのが微笑ましいというか☺️」「遊ばれる言語🤓」「で、上のOpenStruct
って初めて見るけどコレナニ??」「いる、いるぞ、オレオレクラスかと思いきや標準ライブラリにいるぞ↓」「オープンクラスになってるStruct
ってことか」「えー!?🤯」
要素を動的に追加・削除できる手軽な構造体を提供するクラスです。
docs.ruby-lang.orgより
参考: class OpenStruct (Ruby 2.5.0)
参考: class Struct (Ruby 2.5.0)
参考: Ruby のオープンクラスとは (メタプログラミングRuby)
「て、手軽ってw」「ハッシュよりは手堅くていいかも?」「データ構造が違いますけどね😎」「destructure
メソッド↓はどうやらStruct
でdestructするってことか」
# 同記事より
def destructure(method_name)
meta_klass = class << self; self end
method_proc = method(method_name)
unless method_proc.parameters.all? { |t, _| t == :key }
raise "Only works with keyword arguments"
end
arguments = method_proc.parameters.map(&:last)
destructure_proc = -> object {
values = if object.is_a?(Hash)
object
else
arguments.map { |a| [a, object.public_send(a)] }.to_h
end
method_proc.call(values)
}
meta_klass.send(:define_method, method_name, destructure_proc)
method_name
end
「定義したdestructure
DSLを使うとこんな書き方できるのかっ↓😆」「😆」「このdef
はキーワードじゃないんでしょうか?」「たぶんdef adds()
が先に評価されてそれがdestructure
に渡されるんでしょうね」「あーそっか!😳」
# 同記事より
destructure def adds(a: 1, b: 2)
a + b
end
「そういえば確かjoker1007さんがこれと形が似た感じのgemをRubyKaigiで発表してましたよね: アブストラクターとかなんとかいう名前」「何て名前だっけ?」(一同ググる)「abstrikerだっ!!」「そうそう、abstract def foo
みたいなDSLを追加するヤツ: def
の定義がメソッド名のシンボルを返すのを利用して、def
の手前にabstract
っていう、Javaで使われているような構文が使えるようになって抽象クラスを定義できるという」「そこまでして抽象クラスにしたいかな〜?😆」「ま、ま、こういう仕組みを知ってるとより一層楽しめますよね😋」
- リポジトリ: joker1007/abstriker
# 同リポジトリより
class A1
extend Abstriker
abstract def foo
end
end
class A3 < A1
def foo
end
end # => OK
class A2 < A1
end # => raise
Class.new(A1) do
end # => raise
⚓hatefreeweb-gem: ヘイトスピーチ検出API gem(RubyFlowより)
- リポジトリ: nikoma/hatefreeweb-gem
# 同リポジトリより
require 'hatefreeweb'
client = Hatefreeweb::Client.new("Your API KEY HERE")
detection = client.detect("This content is fortunately clean!!","en")
-> 0
detection = client.detect("Here the tone has suffered because of some krauts!!","en")
-> 1
つっつきボイス:「まだ★はゼロですが、変わり種ということで」「このgemでヘイトスピーチを検出するのかと思ったら、hatefreeweb.org↓っていうサービスのAPIを使うのね」「あ、ほんとだ」「このサイトがどのぐらい使われているかはわかりませんが😆」「EmotiScoreなんてのも」「どのぐらいキラワれてるかもわかるんでしょうね☺️」
「過去形で言っちゃいますけど、以前こういうサービスってすごく流行ったんですよね: Twitterでポジティブなコメントやネガティブなコメントを検出してクラスタリングして、ユーザーの気分を探ろう!みたいなのがひと頃の学生の研究発表で山ほどありました😆」「😆」「だいたいみんなおんなじこと考えてる😆」「ひととおり終わった分野🏁」
⚓csvreader: ゼロコンフィグを目指すCSVリーダー(RubyFlowより)
- リポジトリ: csv11/csvreader
# csv11/csvreaderより
txt <<=TXT
1,2,3
4,5,6
TXT
records = Csv.parse( txt ) ## or CsvReader.parse
pp records
# => [["1","2","3"],
# ["4","5","6"]]
# -or-
records = Csv.read( "values.csv" ) ## or CsvReader.read
pp records
# => [["1","2","3"],
# ["4","5","6"]]
# -or-
Csv.foreach( "values.csv" ) do |rec| ## or CsvReader.foreach
pp rec
end
# => ["1","2","3"]
# => ["4","5","6"]
「csvいれぶん!っていうユーザー名が気になる😆」「integer
とかdate
みたいに型推論するようです」
「リポジトリにcsv11.github.ioというリンクがあるんで開いてみた」
「ん?これって公式...じゃないよね?」「この縦を揃える書式、どっかで見たことがあるナ」「『CSV Evolved (for Humans) - Easy-to-Write, Easy-to-Read』ってあるから独自なのかな?🤔」「どうもそうみたい」
# 同サイトより
ID,Name,Code,Area,Pop
ca,Canada,CAN,9984670,34278406
us,United States,USA,9629091,314167157
mx,México [Mexico],MEX,1972550,112322757
...
vs
#####################
# North America
# area (in sq km), pop(ulation)
ca, Canada, CAN, 9 984 670 km², 34 278 406
us, United States, USA, 9 629 091 km², 314 167 157
mx, México [Mexico], MEX, 1 972 550 km², 112 322 757
...
個人的にはシンパシー感じます。
⚓>その他Ruby
昨日の開発者会議では「ブランチ名はmaster、が、呼称は伝統に従い、trunkのまま」という方針が示されました。
— Yukihiro Matsumoto (@yukihiro_matz) October 11, 2018
たぶんそんな感じ。ふりがなをエスパーしてください
— Yukihiro Matsumoto (@yukihiro_matz) October 11, 2018
つっつきボイス:「そうそう、Subversionだと慣例的にtrunkが使われていたけどGitだとmasterなんですよね」「名前変えるのってそんなに大変なんすかね?」「賛同しない人もいそうだし、Ruby trunkって名前も既にあちこちにあるから、そういうのを全部変えて回るのは大変かも」「なるほどなるほど☺️」
「もしかしたら昨今のポリコレの影響でGitが将来改名を迫られたりとか😆」「昔はマスター/スレーブだったのがクライアント/サーバーになったみたいな😆」「主人と奴隷」「まあGitでいうmasterはそっちの意味のマスターではないと思いますが」「master意味多すぎ😢」
「素朴な疑問だけど、マスターテープみたいな『オリジナル/原本/原盤』的な意味のmasterって、マスター/スレーブのmasterと元は同じなのかな?」「反対語のスレーブを仮定しないmasterってことですよね?そういえばどうなんだろう...音楽だとマスターテープ(原盤)とかゴールデンマスターという言葉がありますけど」「元は別なんじゃないかなという気もしますね」「それで言うとGitのorigin/master
って見ようによっては意味がかぶってるのかな🤣オリジナル/オリジナルみたいな」「🤣」(しばらく一同で辞書を引きまくる)
「trunkも辞書引くといろいろ意味があるけど、Subversionの場合は『(木の)幹』なんでしょうね」「そういう意味だとtrunkは語義的にはGitにはふさわしくないのかも?: Gitに幹がありまっか?という話で」「確かに『Gitは本来すべてのブランチが平等であるべき』という考え方ですしね」「その意味ではブランチ名はGitの慣例に従ってmasterにするけど、意味的にはtrunkという決定は何となくワカル」「運用上は変わらないでしょうし」「origin/trunk
なら意味的にも筋は通っていそうだし」
「(初参加の社員に)つっつきではだいたいこんな雑談をよくやってます😆」
⚓クラウド/コンテナ/インフラ/Linux/Serverless
⚓サーバーレスの秘訣(Serverless Statusより)
# 同記事より
$ echo "s3cr3t" | gcloud kms encrypt \
--location=global \
--keyring=serverless-secrets \
--key=app1 \
--ciphertext-file=- \
--plaintext-file=- \
| base64
CiQAePa3VEpDBjS2acf...
つっつきボイス:「割と普通の記事かなと思いつつ」「AWSのIAMや環境変数の話の他にGCPも扱ってると」
「そうそう、IAMとKMSってAWSとGCPのどちらにもあるのが意外に厄介なんですよね〜😅」「言われてみれば😳」「固有のサービス名じゃないんだ?!」「なのでIAMとかKMSの話をしているときって、たいていはAWSの方なんだけど、たまにGCPの話をしている可能性もあるので油断ならない😣」「用語とか普通名詞に近い感じですね」「まあ役割も一緒だからいいんですけど」
参考: AWS Identity and Access Management (IAM - ユーザのアクセスを安全に制御)| AWS
参考: Cloud IAM - Identity & Access Management | Cloud Identity and Access Management | Google Cloud
参考: AWS Key Management Service (暗号化キーを簡単に作成・管理 - KMS)| AWS
参考: Cloud Key Management Service | Cloud KMS | Google Cloud
「ただ、AWSは『IAMでIAMユーザーのアカウントを作る』のに対し、GCPの場合は基本的に『IAMでアカウントに権限を付与する』だったと思う」
後で調べると、GCPの場合は個々のエンドユーザーではなくアプリケーションに属する「サービスアカウント」を作成できるのだそうです。
参考: サービス アカウントの作成と管理 | Cloud Identity and Access Management のドキュメント | Google Cloud
IAMからは離れますが、GCPは最近「Cloud Identity」というソリューションを発表し、これを使うとG-Suiteを使ってない個人用Gmailアカウントのユーザーも一元管理できることもついでに知りました。
参考: Cloud Identity への移行 | Cloud Identity and Access Management のドキュメント | Google Cloud
⚓AWS AmplifyとサーバーレスVueアプリ(Serverless Statusより)
- 元記事: How to Build Serverless Vue Applications with AWS Amplify
- サイト: AWS Amplify -- The foundation for your cloud-powered mobile & web apps
- リポジトリ: aws-amplify/amplify-js
つっつきボイス:「またAWSの新しいサービスかと思ったらJavaScriptのライブラリだそうです」「AWS公式?」「だと思うんですが、上のサイトが微妙にパチもんっぽいデザインで考え込んじゃいました😅」「色とかね☺️」
AWSのブログでもAMplify CLI Toolchainのアナウンスがあり、内容やリポジトリからして公式の位置づけのようです。
「Amplifyって名前わかりづらすぎるでしょ😆」「AMPよりはマシだと思います😆」「なるほどわからん😆が、ググって出た記事↓を大急ぎで読むと、AWSのサービスとの連携の他にJSの拡張とかも含めてAWSと強結合した形で提供するライブラリ、ってことなのかな🤔: AWSと強結合するなら公式だろうし、自分は使わないだろうけど、まあいいんじゃないかと☺️」「もしかするとFirebaseと勝負しようとしてる?🚒」
参考: AWSの次世代JavaScriptライブラリ「AWS Amplify」の概要とReactアプリに導入する手順 #serverless #adventcalendar | DevelopersIO
⚓SQL
⚓PostgreSQLのソートのパフォーマンス改善(Postgres Weeklyより)
-- 同記事より
test=# explain analyze SELECT * FROM t_test ORDER BY x;
QUERY PLAN
--------------------------------------------------------------------------
Sort (cost=804270.42..816770.42 rows=5000000 width=11)
(actual time=4503.484..6475.222 rows=5000000 loops=1)
Sort Key: x
Sort Method: external merge Disk: 102896kB
-> Seq Scan on t_test (cost=0.00..77028.00 rows=5000000 width=11)
(actual time=0.035..282.427 rows=5000000 loops=1)
Planning time: 0.139 ms
Execution time: 6606.637 ms
(6 rows)
つっつきボイス:「PostgreSQLは例によって正攻法でやってけばいいんじゃないかと☺️: クエリプランも読みやすいし」「ぽすぐれのクエリプランは、MySQLほど勘に頼らなくていいし😎」「そういえばうちらのチームにOracleを10年やってる人がいることがこのたび判明しましたね💪」「Oracleチョットワカル😆」「PostgreSQLだとEXPLAIN ANALYZE
で実際に動かした結果を取れるのがいいですよね: あれってMySQLにはなかった気がしますが」「MySQLだとコストは取れなかったかも」「PostgreSQLのEXPLAIN
とEXPLAIN ANALIZE
って実際に動かすかどうかという違いがありますよね」「クエリオプティマイザを通すだけか、クエリオプティマイザを通した上でさらにコストを比較するという違い」
「ぽすぐれはそこを比較できるのがすごく重要: だからこそ結果を見てクエリオプティマイザがの最適化がイマイチだなと気づいたらたとえば手動でFORCE INDEXしたりするなどの手が打てる😍」「MySQLだとそこが勘になりがち😆: 本当は勘じゃないにしても複雑になると勘を働かせないといけなくなる」
参考: 14.1. EXPLAINの利用
⚓JavaScript
⚓Vue.jsの次の構想(JavaScript Weeklyより)
つっつきボイス:「Vue.jsは今後こうなる的なロードマップのようです」「フロント勢はjQueryに死んで欲しいという流れにほぼなりつつあるけど、その先の軽いJSライブラリの当てがあるかというと、ね☺️」「明日はどっちだ」
⚓CSS/HTML/フロントエンド/テスト
⚓CSS Gridプロパティの覚え方(Frontend Focusより)
Understanding the difference between grid-template and grid-autoという記事もありました。
つっつきボイス:「あーこういうヤツね↓」「CSS Gridプロパティは、覚える価値はあると思う🧐」「たぶん書きながら覚えるのが一番早いっすね」
See the Pen Explicit Grid properties by Zell Liew (@zellwk) on CodePen.
「そうそう、Gridはこういう書き方ができるのがいい↓」「おぉ〜😳」
.grid {
grid-template-areas: "header header header header"
". main main . "
"footer footer footer footer";
}
⚓言語よろずの間
⚓書籍『The Art of Prolog』が無料ダウンロード
https://twitter.com/tyru/status/1050172005645922304
つっつきボイス:「ツイートのリンクがそのまま出てますけど😆」「そうなんですよ😭: ユーザー名にアンダースコアが入っているとWordPressが埋め込みに変換できない」
「それにしてもProlog」「ひっさびさに名前を見かけました」「学生のときに一瞬やった気がする」「何というか、関数型言語が台頭するより前のコワモテな言語というイメージ😨」「Prologはやったことなし」
「そういえば最近授業のために作ったJavaScript講習スライドで、『手続き型でない言語』の例をいろいろ調べてたらちょうどProlog(論理型言語)が出てきた」「そういえばそうだった!」「ついでにSQLも非手続き型言語(宣言型言語)だというのも久しぶりに思い出したし」「あー確かに〜!」「あまりに普段からSQL使っているんで気にしてなかった😅」
「『The Art of Prolog』は無料でダウンロードできるそうです: 初版が1980年代みたいですが」「表紙の浮世絵が渋い」「何となく品川の宿に見える」「左上に『品川』って書いてあるし」「ほんとだ😅」
参考: 品川宿 - Wikipedia
後で探したら、さすがMatzがPrologを押さえてました↓。Erlangに影響を与えたんだそうです。
参考: Rubyist のための他言語探訪 【第 13 回】 Prolog
⚓その他
⚓awesome-vscode
- リポジトリ: viatsko/awesome-vscode
GitHubにあるawesome何とかを載せるのは何となく悔しいのですが、えらくパッケージが増えてるので。
つっつきボイス:「最近VSCodeって快進撃ですね」「VSCodeはフロントエンジニアにかなり人気が高いらしい」「それにしてもすごい量のパッケージ」
⚓短時間の観測で将来を高精度に予測?
⚓1mm×2mmのスパイハードウェア
このサイズで成立するのか不思議です。
参考: 中国軍がSupermicro製マザーボードにスパイ・チップを製造段階で仕込んだという仰天報道がもたらしたものとは? - GIGAZINE
つっつきボイス:「そうそう、これどこまで本当に可能なのか謎: Supermicro自身も否定してるし」「スパイチップ、めちゃ小さいけど端子が6つある」「そもそもこのチップにどうやってアタッチするのかがわからないし、ちょっとやそっとじゃこういうことはできないと思うんだけどな〜」
「ちなみにSupermicroといえば自分も昔あこがれてたサーバー向けのハイエンドマザーボードメーカー」「これは知らんかった😳」「何しろマザボだけで10万円、しかしとても安定しているという評判」「そんなに凄かったんだ...」
⚓番外
⚓世界で最も正確な原子時計
参考: 「世界で最も正確な原子時計」を作る研究者に話を聞いたムービーが公開中 - GIGAZINE
そういえば東大でもこのストロンチウム光格子時計を研究してるそうです。従来のセシウム原子時計よりも破格に精度が高いらしいので、身の回りの物体の運動でも相対性理論を検証できるレベルみたいです。早く自転車に積んでみたい。
参考: 原子時計 - Wikipedia
今回は以上です。
バックナンバー(2018年度後半)
週刊Railsウォッチ(20181001)Railsアップグレード記事と各種支援ツール、CLI向けRubyワンライナー集、Rubyアプリをワンバイナリ化ほか
- 20180925 Rails大規模支払サービス開発のノウハウ、RailsのMySQLがutf8mb4に移行、Rpush gemほか
- 20180918 ビューテンプレート探索が高速化、mini_scheduler gem、レガシコントローラのリファクタリングほか
- 20180910 公開つっつき会#2、RSpecは何を参考にするか、イベントソーシング、marginalia gem、負荷テストツールvegetaほか
- 20180903 次世代アップローダーgem「Shrine」、RSpecをどこまでDRYに書くか、Rubyのmainオブジェクトの秘密、GitLabのCookie利用許諾機能はエライほか
- 20180827 Ruby Prize 2018募集開始、Interactor gemとReader Object、書籍『Real World HTTP』、Basecampのヒルチャート機能ほか
- 20180820 Railsで構築されたサイト40選、Deviseはつらいよ、ARのスコープとクラスメソッドの使い分けほか
- 20180813 Rails 5.2.1リリース、sanitize_sql_arrayは5.2からpublicだった、Dev.toがRailsアプリのソースを公開ほか
- 20180806 Rails 5.2.1.rc1リリース、Railsガイド日本語版が5.1に対応、Regexp#match?ほか
- 20180723 Railsdm Day 3 Extremeを後追い、PSDにはZeplin.io、好みの分かれるJSX、負荷テストツール比較ほか
- 20180709 Rails Developers Meetup Day 3 Extreme今週末開催、RailsのSTI/キャッシュ/添付ファイル/Redis/PDF出力、ECMAScript 2018、プロフェッショナルIPv6ほか
- 20180702 Ruby 2.2メンテ正式終了、Ransackがつらくなるとき、書籍『Domain-Driven Rails』、GitHubの高可用MySQLほか
- 20180622 Railsの需要未だ巨大、Unicode 11.0リリース、WebDriverがW3Cで勧告、Flutter.io、2封筒問題ほか
- 20180615 TTY gemとHTTPClient gemは優秀、Rubyの謎フリップフロップ、ちょいゆるRubyスタイルガイドほか
- 20180608 特集「RubyKaigi 2018後の祭り」、
Enumerable#index_with
は優秀、コントローラから@
を消し去るほか
今週の主なニュースソース
ソースの表記されていない項目は独自ルート(TwitterやRSSなど)です。