Slide 1

Slide 1 text

RAILS 5.2(PART 2) RAILS 5.2(PART 2) [email protected]

Slide 2

Slide 2 text

前回までのあらすじ 前回までのあらすじ 前回はRails 5.2のMajor Featuresについて話ました ( ) 今回は各コンポーネントの変更についてです 全部のコミットを紹介するのは時間的に厳しいので、これ は知ってた方が良さそう、という機能についてまとめていま す(独断) https://y-yagi.github.io/presen_rails_5_2/

Slide 3

Slide 3 text

おことわり おことわり 資料は2/18日時点の情報(commit: )を元に作成 されています コードは生き物 7d2b8f3

Slide 4

Slide 4 text

ACTION CABLE ACTION CABLE

Slide 5

Slide 5 text

ALLOWS FOR OTHER COMMON REDIS OPTIONS TO ALLOWS FOR OTHER COMMON REDIS OPTIONS TO BE IN CABLE.YML, BY DEFAULT BE IN CABLE.YML, BY DEFAULT cable.ymlにurl以外のredis-rb用のオプションを指定出来 るようになった host、port、db、password

Slide 6

Slide 6 text

ACTION MAILER ACTION MAILER

Slide 7

Slide 7 text

ALLOW MAILERS TO CONFIGURE THEIR DELIVERY ALLOW MAILERS TO CONFIGURE THEIR DELIVERY JOB JOB delivery jobが固定のクラス(ActionMailer::DeliveryJob) だったのが、mailer毎に指定出来るようになった class MyMailer < ApplicationMailer self.delivery_job = MyCustomDeliveryJob # ... end

Slide 8

Slide 8 text

ADD LOCALE SELECTOR TO EMAIL PREVIEW ADD LOCALE SELECTOR TO EMAIL PREVIEW email previewでlocaleを選択出来るようになった

Slide 9

Slide 9 text

ACTION PACK ACTION PACK

Slide 10

Slide 10 text

RECYCLABLE CACHE KEYS RECYCLABLE CACHE KEYS fragments cachingのcache keyのフォーマットを再利用 可能なフォーマットに変更 元々、デフォルトではcache keyにassocationの version(timestamp)も含むようになっていた(e.g. projects/1-20170202145500) デフォルトだとassociationのversionはupdated_atな 為、レコードが更新される度に新しいkeyが生成されて いた 当然、その度に新しいcacheが生成される。結果、cache がばかすか増える。

Slide 11

Slide 11 text

RECYCLABLE CACHE KEYS RECYCLABLE CACHE KEYS これを、cache keyとcache versionをわけて管理する事に して、cache keyを再利用可能にした 具体的には、先のassocation versionはcache versionと して管理され、keyには含まれなくなった(cacheデータの 中に含まれる)

Slide 12

Slide 12 text

RECYCLABLE CACHE KEYS RECYCLABLE CACHE KEYS # before views/users/index:6e20170b482b34f88f6398ebcfa817c5/users/2-2017051822 ^template path ^template tree digest ^class ^id ^versio # after views/users/index:6e20170b482b34f88f6398ebcfa817c5/users/2 ^template path ^template tree digest ^class ^id version情報はcacheの中に含まれるので、cache取得後、 versionが違えばcacheが更新されるようになった cacheのkey変わるので気をつけてね!

Slide 13

Slide 13 text

RECYCLABLE CACHE KEYS RECYCLABLE CACHE KEYS これにより、 ActiveRecord::Base#cache_versionの戻り 値が変わっている (ActiveRecord::Base.cache_versioningがtrueの場合) # before User.first.cache_key # => "users/1-20180128010605891854" # after User.first.cache_key # => "users/1"

Slide 14

Slide 14 text

EAGER LOAD CONTROLLER ACTIONS TO REDUCE EAGER LOAD CONTROLLER ACTIONS TO REDUCE RESPONSE TIME OF THE FIRST REQUEST RESPONSE TIME OF THE FIRST REQUEST eager_load = trueの場合に、各controllerのactionメソッ ドをサーバ起動時に読む込むよう変更 元々は最初のリクエスト実行時に読みこむようになってい たが、それだと最初のリクエストのreponse timeが遅くな ってしまう為、それを避ける為、サーバ起動時に読みこむよ うになりました

Slide 15

Slide 15 text

AEAD ENCRYPTED COOKIES AND SESSIONS AEAD ENCRYPTED COOKIES AND SESSIONS encrypted cookiesにAES-256-GCMが使われるようにな った なんでAEADが良いかは 参照 既存のcookiesについてはRails側で自動で新しい scheme使うようよしなにやってくれるので、特に対応は不 要(Rails側にバグがなければ) コメント

Slide 16

Slide 16 text

DEFAULT PROTECT FROM FORGERY DEFAULT PROTECT FROM FORGERY デフォルトで protect_from_forgery(protect_from_forgery with: :exception)が指定されるようになった

Slide 17

Slide 17 text

ADD EXPIRY METADATA TO COOKIES AND FRESHEN ADD EXPIRY METADATA TO COOKIES AND FRESHEN EXPIRES OPTION TO SUPPORT DURATION EXPIRES OPTION TO SUPPORT DURATION signed/encrypted cookiesに有効期限が指定出来るよ うになった # Sets a cookie that expires in 1 hour. cookies[:login] = { value: "XJ-122", expires: 1.hour } # Sets a cookie that expires at a specific time. cookies[:login] = { value: "XJ-122", expires: Time.utc(2020, 10, 15, 有効期限後は値が読み込めなくなる

Slide 18

Slide 18 text

ADD KEY ROTATION TO MESSAGEENCRYPTOR AND ADD KEY ROTATION TO MESSAGEENCRYPTOR AND MESSAGEVERIFIER AND SIMPLIFY THE COOKIES MESSAGEVERIFIER AND SIMPLIFY THE COOKIES MIDDLEWARE MIDDLEWARE MessageEncryptor`クラス及びMessageVeri erクラスに key rotationのサポートを追加 それぞれrotateメソッドが提供されおり、keyのrotationが 出来るようになっている old_secret = SecureRandom.random_bytes(32) old_message = ActiveSupport::MessageEncryptor.new(old_secret, cipher: new_secret = SecureRandom.random_bytes(32) encryptor = ActiveSupport::MessageEncryptor.new(new_secret, cipher: " encryptor.rotate(old_secret) encryptor.decrypt_and_verify(old_message) # => "old"

Slide 19

Slide 19 text

ADD KEY ROTATION TO MESSAGEENCRYPTOR AND ADD KEY ROTATION TO MESSAGEENCRYPTOR AND MESSAGEVERIFIER AND SIMPLIFY THE COOKIES MESSAGEVERIFIER AND SIMPLIFY THE COOKIES MIDDLEWARE MIDDLEWARE これを利用してEncrypted Cookies及びSigned Cookies のkeyのrotationが出来るようになった # signed cookies を SHA1 から SHA256に変更する場合 Rails.application.config.action_dispatch.signed_cookie_digest = "SHA2 Rails.application.config.action_dispatch.cookies_rotations.tap do |co cookies.rotate :signed, digest: "SHA1" end

Slide 20

Slide 20 text

ADD HEADLESS CHROME DRIVER TO SYSTEM TESTS ADD HEADLESS CHROME DRIVER TO SYSTEM TESTS System testにheadless chrome driverのサポートが追 加された class DrivenBySeleniumWithHeadlessChrome < ActionDispatch::SystemTest driven_by :selenium, using: :headless_chrome end headless refox driverのサポートも追加された Add headless refox driver to System Tests

Slide 21

Slide 21 text

MAKE SCREENSHOTS DEFAULT TO "SIMPLE" FORMAT MAKE SCREENSHOTS DEFAULT TO "SIMPLE" FORMAT System testのスクリーンショットのデフォルト が"simple"になった iTerm2使っている場合、5.1まではデフォルトでターミナルに スクリーンショットが出ていたのが出なくなる

Slide 22

Slide 22 text

REGISTER MOST POPULAR AUDIO/VIDEO/FONT REGISTER MOST POPULAR AUDIO/VIDEO/FONT MIME TYPES SUPPORTED BY MODERN… MIME TYPES SUPPORTED BY MODERN… デフォルトで登録されているmime typeに、 audio/video/fontのmime typesが追加された "audio/webm"とか"video/webm"等々

Slide 23

Slide 23 text

ADD SECURE ADD SECURE X-DOWNLOAD-OPTIONS X-DOWNLOAD-OPTIONS AND `X- AND `X- PERMITTED-CROSS-DOMAIN-POLICIE… PERMITTED-CROSS-DOMAIN-POLICIE… default headers setの変更。後から も入ったので、最終的には 下記のようになっている(X-Download-Options以降が追加 されたheader)。 Add 'Referrer-Policy' header to default headers set config.action_dispatch.default_headers = { "X-Frame-Options" => "SAMEORIGIN", "X-XSS-Protection" => "1; mode=block", "X-Content-Type-Options" => "nosniff", "X-Download-Options" => "noopen", "X-Permitted-Cross-Domain-Policies" => "none", "Referrer-Policy" => "strict-origin-when-cross-origin" }

Slide 24

Slide 24 text

ACTION VIEW ACTION VIEW

Slide 25

Slide 25 text

ADD SRCSET OPTION TO IMAGE_TAG HELPER ADD SRCSET OPTION TO IMAGE_TAG HELPER image_tag メソッドにsrcset属性が指定出来るようになっ た srcset属性については 参照 srcset属性について - Qiita

Slide 26

Slide 26 text

DO NOT GENERATE DEFAULT ALT TEXT FOR IMAGES DO NOT GENERATE DEFAULT ALT TEXT FOR IMAGES imageタグを生成する際、デフォルトではalt属性を生成し ないようになった 元々は、image_tag "logo.png"だと、下記のようなHTML が生成されていた Logo

Slide 27

Slide 27 text

DO NOT GENERATE DEFAULT ALT TEXT FOR IMAGES DO NOT GENERATE DEFAULT ALT TEXT FOR IMAGES 上記の場合、スクリーンリーダーは、"Logo"というテキスト を読みあげる が、これは実際は何も意味もない情報(logo.pngが会社の ロゴならその会社名が読み上げらないと意味が無い) というわけで、デフォルトで生成されるalt属性には意味が ない、どころが邪魔になってしまっている、という事でデフォ ルトではalt属性を生成しないようにしたとの事

Slide 28

Slide 28 text

CHANGE CHANGE FORM_WITH FORM_WITH TO GENERATES IDS BY DEFAULT. TO GENERATES IDS BY DEFAULT. form_with配下のタグで、デフォルトでid属性を生成するよ うになった form_withが最初に実装された時は、頻繁に重複したID を生成してしまいそんなに使われる情報では無いだろう、と いう事でidは生成しないようにしていたのだが、Capybara でテストをする際等にidは必要だろう、という事で、デフォル トで生成するよういなりました idを生成したく無い場合(5.1と同じ挙動)は con g.action_view.form_with_generates_idsにfalse を指定すればOK

Slide 29

Slide 29 text

ACTIVE JOB ACTIVE JOB

Slide 30

Slide 30 text

ACTIVE JOB ACTIVE JOB これといってなにもなくてだね がバックポートされるかなーと思ったがされなかった Introduce custom serializers to ActiveJob arguments

Slide 31

Slide 31 text

ACTIVE MODEL ACTIVE MODEL

Slide 32

Slide 32 text

ALLOW PASSING A PROC OR SYMBOL AS AN ALLOW PASSING A PROC OR SYMBOL AS AN ARGUMENT TO LENGTH VALIDATOR VALUES ARGUMENT TO LENGTH VALIDATOR VALUES length validatorにProc, Symbolが渡せるようになった class Topic include ActiveModel::Validations attr_accessor :title, :foo validates :title, length: { maximum: ->(topic) { topic.max_length_f def max_length_for_title if foo 5 else 10 end end

Slide 33

Slide 33 text

ATTRIBUTES API? ATTRIBUTES API? Active Recordにあったattributes API用のclass / moduleが Active Model配下に移動された これにより、Active Modeldでもattributes APIが使えるようには っている ただ、まだpublic APIではないからね Start bringing attributes API to AM Move Attribute and AttributeSet to ActiveModel https://github.com/rails/rails/pull/31848#issuecomm 362130685

Slide 34

Slide 34 text

ACTIVE RECORD ACTIVE RECORD

Slide 35

Slide 35 text

SUPPORT DESCENDING INDEXES FOR MYSQL SUPPORT DESCENDING INDEXES FOR MYSQL Descending Indexが指定出来るようになった(MySQL 8.0.1以降) e.g. "add_index [: rm_id, :type, :rating], name: "company_index", length: { type: 10 }, order: { rating: :desc }" 参考:MySQL 8.0 Labs – Descending Indexes in MySQL

Slide 36

Slide 36 text

CHANGE SQLITE3 BOOLEAN SERIALIZATION TO USE 1 CHANGE SQLITE3 BOOLEAN SERIALIZATION TO USE 1 AND 0 AND 0 SQLite 3 adapterでbooleanの値を保持するのにString のt / fを使用していたのを、Integer(1 / 0)を使用するよう 修正した 1と0はSQLite側でも true / falseと認識する為(t / fで はtrue / falseとは認識されない)。 元々t / fで保持していた値は、手動で移行する必要がある (e.g. ExampleModel.where("boolean_column = 't'").update_all(boolean_column: 1))

Slide 37

Slide 37 text

DISALLOW RAW SQL IN DANGEROUS AR METHODS DISALLOW RAW SQL IN DANGEROUS AR METHODS orderとpluckの引数に生SQLをそのまま渡すのが deprecateになった User.order("LENGTH(name)") # => DEPRECATION WARNING: Dangerous query method (method whose argume メッセージの通り、Arel.sqlメソッドでラップしてあげる必要 がある Article.order(params[:my_order])のような形でメソッド を使用した場合に、SQL injectionが起こるのを防ぐ為、と の事

Slide 38

Slide 38 text

DISALLOW RAW SQL IN DANGEROUS AR METHODS DISALLOW RAW SQL IN DANGEROUS AR METHODS 5.2時点ではdeprecateメッセージが表示されるだ、6.0で はUnknownAttributeReferenceがraiseされるようになる 引続き生SQLを渡すようにしたい場合、 ActiveRecord::Base.allow_unsafe_raw_sql に:disabledを指定すればOK

Slide 39

Slide 39 text

FLUSH IDLE DATABASE CONNECTIONS FLUSH IDLE DATABASE CONNECTIONS idle状態のコネクションを自動で切断するようになった デフォルトでは300秒以上使われていないコネクションが 自動で切断されるようになっている 切断までの時間はcon g(idle_timeout)で変更可能

Slide 40

Slide 40 text

IMPROVE AR CONNECTION FORK SAFETY IMPROVE AR CONNECTION FORK SAFETY Active Recordのconnectionを保持するプロセスをforkし た際、親プロセスに属しているconnectionを破棄するよう になった 子プロセスで親プロセスのconnectionに対して誤って quit/shutdown/goodbye等のメッセージ送信しないよ うにする為

Slide 41

Slide 41 text

DROP THE BEFORE_FORK/ON_WORKER_BOOT DROP THE BEFORE_FORK/ON_WORKER_BOOT ADVICE ADVICE 先の二つの対応により、Active Recordのconnectionを保 持してるプロセスをforkした際のケアが不要になった con g/puma.rbに記載されていた before_fork do ActiveRecord::Base.connection_pool.disconnect! if defined?(ActiveRe end はもう不要

Slide 42

Slide 42 text

BUILD A MULTI-STATEMENT QUERY WHEN BUILD A MULTI-STATEMENT QUERY WHEN INSERTING FIXTURES INSERTING FIXTURES xturesをinsertする際に、multi statement queryを使用 するようになった これにより、元々はtable毎にqueryを実行していたのを、一 つのqueryでまとめてデータを作成(削除も)するようになっ た

Slide 43

Slide 43 text

LOG THE ORIGINAL CALL SITE FOR AN LOG THE ORIGINAL CALL SITE FOR AN ACTIVERECORD QUERY ACTIVERECORD QUERY Active Recordのqueryが発行された際のcallersをログに 表示するするようになった # log/development.log User Load (0.2ms) SELECT "users".* FROM "users" ↳ app/views/users/index.html.erb:14 ようは 表示されるのはserverのログでだけ(rails consoleでは出 ない) active-record-query-trace

Slide 44

Slide 44 text

ADD BULK ALTER SUPPORT FOR POSTGRESQL ADD BULK ALTER SUPPORT FOR POSTGRESQL PostgreSQL adapterにbulk alterのサポートが追加され た PostgreSQLでもchange_tableにbulk: trueオプションを 指定した場合、一つのALTER TABLEでSQLが実行される ようになった

Slide 45

Slide 45 text

SUPPORT FOR POSTGRESQL FOREIGN TABLES SUPPORT FOR POSTGRESQL FOREIGN TABLES PostgreSQLのforeign tablesをサポート foreign tablesで定義されたtableも、普通のtableやview と同様にActive Recordから操作出来るようになった

Slide 46

Slide 46 text

MAKE MAKE SANITIZE_SQL_ SANITIZE_SQL_ METHODS PUBLIC METHODS PUBLIC sanitize_sql_xxxメソッド(sanitize_sql_likeとか、 sanitize_sql_array等々)の可視性をpublicに変更した これにより、Modelの外から使用する際にsendを使う必要 が無くなった

Slide 47

Slide 47 text

ADD A #UP_ONLY METHOD TO MIGRATIONS ADD A #UP_ONLY METHOD TO MIGRATIONS migrationにupのときだけ使用出来るup_onlyメソッドが追 加された class AddPublishedToPosts < ActiveRecord::Migration[5.2] def change add_column :posts, :published, :boolean, default: false up_only do execute "update posts set published = 'true'" end end end

Slide 48

Slide 48 text

NEW ERROR CLASS NEW ERROR CLASS Add new error class StatementTimeout which will be raised when statement timeout exceeded Add new error class QueryCanceled which will be raised when canceling statement due to user request

Slide 49

Slide 49 text

NEW ERROR CLASS NEW ERROR CLASS LockWaitTimeout(最初はTransactionTimeoutだった が、後から LockWaitTimeoutにリネーム Add TransactionTimeout for MySQL error code 1205 Raise TransactionTimeout when lock wait timeout exceeded for PG ada… Rename TransactionTimeout to more descriptive LockWaitTimeout

Slide 50

Slide 50 text

REFACTOR ACTIVE RECORD TO LET AREL MANAGE REFACTOR ACTIVE RECORD TO LET AREL MANAGE BIND PARAMS BIND PARAMS Active Recordで行っていたbind paramsの管理をArelで 行うようリファクタリング ユーザに直接影響がある事はそんなに無い筈(private APIを使ってなければ)だが、bind parameterいじって何か してたりしたらきをつけて

Slide 51

Slide 51 text

その他改善の詳細については、 ご参照 Rails 5.2のActive Recordの 改善

Slide 52

Slide 52 text

ACTIVE SUPPORT ACTIVE SUPPORT

Slide 53

Slide 53 text

ACTIVESUPPORT::CURRENTATTRIBUTES PROVIDES A ACTIVESUPPORT::CURRENTATTRIBUTES PROVIDES A THREAD-ISOLATED ATTRIBUTES SINGLETON THREAD-ISOLATED ATTRIBUTES SINGLETON スレッド毎に独立したattibutesを管理するための ActiveSupport::CurrentAttributesクラスが追加された リクエスト毎のattribute(リクエストIDやUA等)をシステ ム全体で使用可能にする、のが主なユースケースとの事 リクエトの前後で自動でattributeのresetが行われるよ うになっている 具体的な使い方は 参照 Doc

Slide 54

Slide 54 text

ADD OPTION FOR CLASS_ATTRIBUTE DEFAULT ADD OPTION FOR CLASS_ATTRIBUTE DEFAULT class_attributeにdefaultオプションが追加された "class_attribute :_layout_conditions, instance_accessor: false, default: {}"みたいに書ける mattr_accessor、及び、関連メソッドにも同様にdefaultオ プションが追加された Introduce mattr_accessor default option

Slide 55

Slide 55 text

ADD NEXT AND PREVIOUS DAY OF WEEK API TO ADD NEXT AND PREVIOUS DAY OF WEEK API TO ACTIVESUPPORT ACTIVESUPPORT 次、又は、前の曜日を取得するための Date#prev_occurring、Date#next_occurringメソッド が追加された Date.today # => Wed, 31 May 2017 Date.today.next_occurring(:monday) # => Mon, 05 Jun 2017 00:00:00 UTC +00:00 Date.today.prev_occurring(:monday) # => Mon, 29 May 2017 00:00:00 UTC +00:00

Slide 56

Slide 56 text

CACHE: WRITE_MULTI CACHE: WRITE_MULTI ActiveSupport::Cache::Storeにwrite_multiメソッドが追 加された 名前の通りで複数データをまとめて書き込む為のメソッ ド e.g. Rails.cache.write_multi foo: 'bar', baz: 'qux' Redis adapterだとMSETを使うようになるので、一個一個 書き込むよりはやい 他のadapterは、(今の所)複数回write_entryするだけな の性能的には変わらない

Slide 57

Slide 57 text

USE SHA-1 FOR NON-SENSITIVE DIGESTS BY USE SHA-1 FOR NON-SENSITIVE DIGESTS BY DEFAULT DEFAULT digestsの生成にMD5を使っていたのを、SHA-1を使うよう になった ETag headerとか con g.active_support.use_hash_digest_classに digest classを指定する事で、SHA-1以外を使用する事も 可能 Initial support for running Rails on FIPS-certi ed systems

Slide 58

Slide 58 text

ADD SUPPORT FOR CONNECTION POOLING ON ADD SUPPORT FOR CONNECTION POOLING ON REDISCACHESTORE REDISCACHESTORE redis cache storeにconnection poolingのサポートを追 加 ool_sizeオプションを指定した場合のみconnection pool が使用されるようになってる connection pool部分の実装は gemを使用している mem cache storeでも同様のサポートが入っている mperham/connection_pool Support for connection pooling on mem cache store

Slide 59

Slide 59 text

REMOVE TIME STUBS AFTER EACH TEST REMOVE TIME STUBS AFTER EACH TEST ActiveSupport::Testing::TimeHelpersをincludeしている 場合、テストの後処理で自動でtravel_backが呼ばれるよ うになった

Slide 60

Slide 60 text

RAILTIES RAILTIES

Slide 61

Slide 61 text

ADD BOOTSNAP TO DEFAULT GEMFILE ADD BOOTSNAP TO DEFAULT GEMFILE デフォルトで生成されるGem leにbootsnapが追加された Gem leにbootsnapを追加、及び、con g/boot.rbで bootsnap/setupをrequireするようになっただけ rails newに--skip-bootsnapオプションも追加済み

Slide 62

Slide 62 text

ALLOW TO PASS A CONNECTION TO THE ALLOW TO PASS A CONNECTION TO THE DBCONSOLE DBCONSOLE COMMAND COMMAND rails dbconsoleにconnection名を指定出来るようになっ た bin/rails dbconsole -c replica 3-level database con gurationを使っている場合に便利 なのだが、3-level database con guration自体がまだ ふんわりしている

Slide 63

Slide 63 text

その他内部的なはなし その他内部的なはなし

Slide 64

Slide 64 text

USE FROZEN STRING LITERAL USE FROZEN STRING LITERAL Railsのコードすべてに対してfrozen string literalが指定 されるようになりました 以下略 Railsのバージョンをあげたらいきなり"can't modify frozen String"が出るようになった場合、Rails側の問題の 可能性もあるので、issueください JRubyとかあやしい Use frozen-string-literal in ActiveSupport Use frozen string literal in actionmailer/

Slide 65

Slide 65 text

まとめ まとめ 他にも大量のBug Fixや改善があるんで とりあえず5.2にあげて