Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rails 6.0 part 2

y-yagi
June 25, 2019
3.5k

Rails 6.0 part 2

Ginza.rb 72

y-yagi

June 25, 2019
Tweet

Transcript

  1. Action CableのソースがCo eeScriptで書かれていたのを JavaScriptに変換 この対応の影響で一部APIに非互換が発生している 詳細は を見てね 因みにrails-ujsはまだCo eeScript(JavaScriptへの移行予定はあ る)

    CONVERT THE ACTION CABLE JAVASCRIPT CONVERT THE ACTION CABLE JAVASCRIPT PACKAGE FROM COFFEESCRIPT TO ES2015 AND PACKAGE FROM COFFEESCRIPT TO ES2015 AND PUBLISH THE SOURCE CODE IN THE NPM PUBLISH THE SOURCE CODE IN THE NPM DISTRIBUTION DISTRIBUTION https://edgeguides.rubyonrails.org/upgrading_ruby_on_rails.html#actio cable-javascript-api-changes
  2. システムテストにbrowser capabilitiesを指定出来るようになった driven_byにブロックを指定+そのブロックでbrowser capabilitiesを指定出来る ALLOW ALLOW ActionDispatch::SystemTestCase.driven_by ActionDispatch::SystemTestCase.driven_by TO TO

    BE CALLED WITH A BLOCK TO DEFINE SPECIFIC BE CALLED WITH A BLOCK TO DEFINE SPECIFIC BROWSER CAPABILITIES BROWSER CAPABILITIES driven_by :selenium, using: :headless_chrome, screen_size: [14 do |driver_option| # driver_option.class => Selenium::WebDriver::Chrome::Opti driver_option.add_emulation(device_name: 'iPhone 6') end
  3. Signed / Encrypted cookiesにpurpose及びexpiryメタデータを 埋め込むようになった purposeはCookieの値をコピーして別のCookieとしてコピー出来 ないようにする為(値は自動で指定される) ADD PURPOSE AND

    EXPIRY METADATA INSIDE ADD PURPOSE AND EXPIRY METADATA INSIDE SIGNED/ENCRYPTED COOKIES TO PREVENT SIGNED/ENCRYPTED COOKIES TO PREVENT COPYING THE VALUE OF COOKIES INTO ONE COPYING THE VALUE OF COOKIES INTO ONE ANOTHER ANOTHER
  4. メタデータが埋め込まれたcookieは古いバージョンで作られた cookieと互換性がないので注意が必要 メタデータはデフォルトでは無効されており、 action_dispatch.use_cookies_with_metadataにtrueを指定した場合のみ 有効化される GSoC案件 ADD PURPOSE AND EXPIRY

    METADATA INSIDE ADD PURPOSE AND EXPIRY METADATA INSIDE SIGNED/ENCRYPTED COOKIES TO PREVENT SIGNED/ENCRYPTED COOKIES TO PREVENT COPYING THE VALUE OF COOKIES INTO ONE COPYING THE VALUE OF COOKIES INTO ONE ANOTHER ANOTHER https://gist.github.com/assain/fed04b9b610b8c190566a1956f523cc1
  5. template rendering instrumentation(ログにでるやつ)で Allocationsの値(GC.stat :total_allocated_objectsの値)を表示 するようになった ADD ALLOCATIONS TO TEMPLATE

    RENDERER ADD ALLOCATIONS TO TEMPLATE RENDERER SUBSCRIPTION SUBSCRIPTION Rendering posts/new.html.erb within layouts/application Rendered posts/_form.html.erb (Duration: 7.1ms | Allocations Rendered posts/new.html.erb within layouts/application (Dura Completed 200 OK in 858ms (Views: 848.4ms | ActiveRecord: 0.4m
  6. REFACTORING ACTION VIEW REFACTORING ACTION VIEW (PR一部) Fix memory leaks

    in development Add a nalizer to inline templates No nil format on templates Templates have one format Pass locals in to the template object on construction Pass the template format to the digestor Move compiled ERB to an AV::Base subclass Speed up partial rendering by caching "variable" calculation More Read-Only Changes Tighten up the AV::Base constructor Make the lookup context more "read-only" Template Handler Refactoring
  7. 辺りをご参考 ADD SUPPORT FOR CUSTOM SERIALIZERS FOR ADD SUPPORT FOR

    CUSTOM SERIALIZERS FOR ACTIVE JOB ARGUMENTS ACTIVE JOB ARGUMENTS class MoneySerializer < ActiveJob::Serializers::ObjectSerializ def serialize(money) super("amount" => money.amount, "currency" => money.curren end def deserialize(hash) Money.new(hash["amount"], hash["currency"]) end private def klass Money end end Rails.application.config.active_job.custom_serializers << Mone https://github.com/rails/rails/tree/master/activejob/lib/active_job/serializers
  8. 上記のように、model + attributes + format、又は、model + formatのkeyを見るようになっている これはcon g.active_model.i18n_customize_full_messageを trueにした場合のみ有効(デフォルトはfalse)

    ADD A CONFIGURATION OPTION TO ADD A CONFIGURATION OPTION TO CUSTOMIZE FORMAT OF THE CUSTOMIZE FORMAT OF THE ActiveModel::Errors#full_message ActiveModel::Errors#full_message activemodel.errors.models.person/contacts/addresses.attributes activemodel.errors.models.person/contacts/addresses.format activemodel.errors.models.person.attributes.name.format activemodel.errors.models.person.format
  9. createしてレコードが既にある場合 (ActiveRecord::RecordNotUniqueでエラーになった場合)に nd を実行 ADD ADD ActiveRecord::Base.create_or_find_by ActiveRecord::Base.create_or_find_by/ /! !

    def create_or_find_by(attributes, &block) transaction(requires_new: true) { create(attributes, &block) rescue ActiveRecord::RecordNotUnique find_by!(attributes) end
  10. bulk insert用のinsert_all / insert_all! / upsert_allメソッドを追 加 callback、validationは実行されないので、callbackで設定してい る値は明示的に指定する必要がる created_at

    / updated_atとかも ADD INSERT_ALL TO ACTIVERECORD MODELS ADD INSERT_ALL TO ACTIVERECORD MODELS User.insert_all!([ { name: 'a', created_at: Time.current, updated_at: Time.curr { name: 'b', created_at: Time.current, updated_at: Time.curr { name: 'c', created_at: Time.current, updated_at: Time.curr ])
  11. insert_all!はunique constraintに違反した場合 ActiveRecord::RecordNotUniqueをraiseするようになっている insert_allは無視(実行するクエリーが違う) ADD INSERT_ALL TO ACTIVERECORD MODELS ADD

    INSERT_ALL TO ACTIVERECORD MODELS User.insert_all([ { id: 1, name: 'a', created_at: Time.current, updated_at: Ti { id: 1, name: 'b', created_at: Time.current, updated_at: Ti ]) # => INSERT INTO "users"("id","name","created_at","updated_at" User.insert_all!([ { id: 1, name: 'a', created_at: Time.current, updated_at: Ti { id: 1, name: 'b', created_at: Time.current, updated_at: Ti ]) # => INSERT INTO "users"("id","name","created_at","updated_at" # => ActiveRecord::RecordNotUnique (PG::UniqueViolation: ERROR
  12. upsert_allは名前の通りでUPSERT(PostgreSQL / SQLiteでは ON CONFLICT、MySQLではON DUPLICATE KEY UPDATE)が 使用されるようになってる  当然DBはそれらの機能を使用出来るバージョンである必要がある

    ADD INSERT_ALL TO ACTIVERECORD MODELS ADD INSERT_ALL TO ACTIVERECORD MODELS User.upsert_all([ { id: 1, name: 'a', created_at: Time.current, updated_at: Ti { id: 2, name: 'b', created_at: Time.current, updated_at: Ti ]) User.upsert_all([ { id: 1, name: 'a', created_at: Time.current, updated_at: Ti { id: 2, name: 'b', created_at: Time.current, updated_at: Ti ]) # => INSERT INTO "users"("id","name","created_at","updated_at"
  13. enumでnegative scope(not_xxx)も定義するようになった メソッド名のコンフリ気をつけてね ADD NEGATIVE SCOPES FOR ALL ENUM VALUES

    ADD NEGATIVE SCOPES FOR ALL ENUM VALUES class Post < ActiveRecord::Base enum status: %i[ drafted active trashed ] end Post.not_drafted # => where.not(status: :drafted) Post.not_active # => where.not(status: :active) Post.not_trashed # => where.not(status: :trashed)
  14. #inspect及び#pretty_printでattributesを出力する際に、特定 のattributeの値を lter出来るようになった lterしたい値は lter_attributesで指定できる デフォルトでは、Rails.application.con g. lter_parametersに指 定されている値が lter_attributesに指定される

    ADD THE ABILITY TO FILTER OUT SENSITIVE ADD THE ABILITY TO FILTER OUT SENSITIVE DATA IN DATA IN #inspect #inspect User.first.inspect #=> "#<User id: 1, name: \"Taro\", secret: \"secret\", created ActiveRecord::Base.filter_attributes = [:secret] User.first.inspect #=> "#<User id: 1, name: \"Taro\", secret: [FILTERED], created
  15. whereでendless rangeが使えるよ PostgreSQLのrange typesにでもendless rangeが使えるよ ADD SUPPORT IN ADD SUPPORT

    IN #where #where FOR ENDLESS RANGES FOR ENDLESS RANGES INTRODUCED IN RUBY 2.6 INTRODUCED IN RUBY 2.6 User.where(id: 1..).to_sql #=> "SELECT \"users\".* FROM \"users\" WHERE \"users\".\"id\" PostgreSQL: Support endless range values for range types
  16. single-valueを取得する為のメソッド pluck同様、record objectは生成せずに値だけを取得する limit(1).pluck(*column_names). rstのショートハンド ADD ADD Relation#pick Relation#pick AS

    SHORT-HAND FOR AS SHORT-HAND FOR SINGLE-VALUE PLUCKS SINGLE-VALUE PLUCKS Person.where(id: 1).pick(:name) # SELECT people.name FROM people WHERE id = 1 LIMIT 1 # => 'David' Person.where(id: 1).pick(:name, :email_address) # SELECT people.name, people.email_address FROM people WHERE i # => [ 'David', '[email protected]' ]
  17. 条件を指定してのdestroy / deleteを行う為メソッド where(condition).destroy_all とwhere(condition).delete_all のショートハ ンド ADD ADD #destroy_by

    #destroy_by AND AND #delete_by #delete_by FOR FOR CONDITIONAL REMOVALS CONDITIONAL REMOVALS Person.destroy_by(id: 13) Person.delete_by("published_at < ?", 2.weeks.ago)
  18. select statementを再指定する為のメソッド unscope(:select).select( elds)のショートハンド ADD ADD reselect reselect METHOD, WHICH

    IS A SHORT- METHOD, WHICH IS A SHORT- HAND FOR HAND FOR unscope(:select).select(fields) unscope(:select).select(fields) Post.select(:title, :body).reselect(:created_at) # => SELECT `posts.created_at` FROM `posts`
  19. 名前の通り複数のレコードに対してtouchする為のメソッド ADD ADD touch_all touch_all METHOD TO METHOD TO ActiveRecord::Relation

    ActiveRecord::Relation Person.where(name: 'David').touch_all # => "UPDATE \"people\" SET \"updated_at\" = '2018-01-04 22:55
  20. queryにSQLコメントを追加する為のメソッド 引数にはArrayを指定する事が出来、Arrayを指定した場合は別 のコメントとして出力される ADD ADD ActiveRecord::Relation#annotate ActiveRecord::Relation#annotate FOR FOR ADDING

    SQL COMMENTS TO ADDING SQL COMMENTS TO ACTIVERECORD::RELATION QUERIES ACTIVERECORD::RELATION QUERIES Post.where(id: 123).annotate("this is a comment").to_sql # SELECT "posts".* FROM "posts" WHERE "posts"."id" = 123 /* th User.annotate("selecting", "user", "names").select(:name) # SELECT "users"."name" FROM "users" /* selecting */ /* user *
  21. Optimizer Hintsを指定する為のメソッド MySQLは本体でサポートされているが、PostgreSQLの場合は別 途 moduleのインストールが必要 ADD SUPPORT FOR SETTING OPTIMIZER

    HINTS ADD SUPPORT FOR SETTING OPTIMIZER HINTS ON DATABASES ON DATABASES # MySQL Topic.optimizer_hints("MAX_EXECUTION_TIME(50000)", "NO_INDEX_M # SELECT /*+ MAX_EXECUTION_TIME(50000) NO_INDEX_MERGE(topics) # PostgreSQL(pg_hint_plan) Topic.optimizer_hints("SeqScan(topics)", "Parallel(topics 8)") # SELECT /*+ SeqScan(topics) Parallel(topics 8) */ "topics".* pg_hint_plan
  22. rstやlastのようなordered nder methodsでorderに使用する カラムを指定出来るようになった primary keyにUUIDのようなauto-incrementing integerじゃな い値を使用している場合に、primary keyでorderしても結果は期 待通りにならない(

    rstを使用しても最初の値は取得出来ない) 為、そのような場合に任意のカラムでorder出来るようにする為 MAKE IT POSSIBLE TO OVERRIDE THE IMPLICIT MAKE IT POSSIBLE TO OVERRIDE THE IMPLICIT ORDER COLUMN ORDER COLUMN class User < ActiveRecord::Base self.implicit_order_column = "created_at" end User.first # =>User Load (0.2ms) SELECT "users".* FROM "users" ORDER BY
  23. MySQLのデフォルトの文字セットがutf8mb4になった 詳細はyahondaさんの資料ご参照 Rails 6 MySQLのutf8mb4対応とは何であって何ではないのか USE THE UTF8MB4 CHARACTER SET

    BY USE THE UTF8MB4 CHARACTER SET BY DEFAULT IN MYSQL DEFAULT IN MYSQL https://speakerdeck.com/yahonda/rails-6-mysqlfalseutf8mb4dui- ying-tohahe-deatutehe-dehanaifalseka
  24. BUMP THE MINIMUM VERSIONシリーズ BUMP THE MINIMUM VERSIONシリーズ Bump the

    minimum SQLite version to 3.8. Bump the minimum version of the sqlite3 gem to 1.4. Bump the minimum MySQL version to 5.5.8. Bump the minimum PostgreSQL version to 9.3
  25. truncate + seedを実行するタスク ADD ADD rails db:seed:replant rails db:seed:replant THAT

    TRUNCATES THAT TRUNCATES TABLES OF EACH DATABASEFOR THE CURRENT TABLES OF EACH DATABASEFOR THE CURRENT ENVIRONMENT AND LOADS THE SEEDS ENVIRONMENT AND LOADS THE SEEDS
  26. その他DEPRECATED その他DEPRECATED については、kamipoさんのブログをご参照ください Rails 6.0でDeprecatedになるActive Recordの振る舞い3つ - かみぽわーる Deprecate mismatched

    collation comparison for uniquness validator Deprecate where.not working as NOR and will be changed to NAND in Rails 6.1 Deprecate using class level querying methods if the receiver scope regarded as leaked https://blog.kamipo.net/entry/2019/05/15/152652
  27. ファイルの変換処理にImageMagick(mini_magick gem)を直接 使用していたのを、 gemを使用するよう変更 image_processingはGraphicsMagickもサポートしているのでフ ァイルの変換処理に (ruby-vips gem)も使用出来るように なった vipsを使用したい場合はcon

    g.active_storage.variant_processorにvipsを 指定すればOK これによりmini_magick gemを直接使用するのはdepecateにな った 因みに、変換処理でImageMagickのオペレーションを直接指定していたのを、 image_processingが提供するメソッド(resize_to_ t、resize_to_ ll等々)を 使用するよう変更する必要があります USE THE USE THE image_processing image_processing GEM FOR ACTIVE GEM FOR ACTIVE STORAGE VARIANTS. THIS REPLACES USING STORAGE VARIANTS. THIS REPLACES USING mini_magick mini_magick DIRECTLY DIRECTLY image_processing libvips
  28. 新規にアップロードしたファイルが、オブジェクトにアサインされた 際に即座に保存されていたのを、そのアサインしたオブジェクトが saveされた後に保存するよう変更 上記のようなコードで、Rails 5.2ではアサインされた際に即座にフ ァイルが保存されてしましたが、6.0では@userのsaveが成功した 後にファイルが保存されるようになった ファイル設定 / 保存の間にバリデーションを挟めるようにする為、だったはずが

    バリデーション機能は結局まだ入らなかった REPLACE EXISTING IMAGES INSTEAD OF REPLACE EXISTING IMAGES INSTEAD OF ADDING TO THEM WHEN UPDATING AN ADDING TO THEM WHEN UPDATING AN ATTACHED MODEL VIA ATTACHED MODEL VIA update update OR OR update! update! WITH, WITH, SAY, `@USER.UPDATE!(IMAGES: [ … ] SAY, `@USER.UPDATE!(IMAGES: [ … ] @user.avatar = params[:avatar]
  29. これにより、update時の挙動がファイルの追加から置き換えに変 更になった(非互換) フラグで古い挙動になるようにすべきだよね、という話があるがま だ未対応 REPLACE EXISTING IMAGES INSTEAD OF REPLACE

    EXISTING IMAGES INSTEAD OF ADDING TO THEM WHEN UPDATING AN ADDING TO THEM WHEN UPDATING AN ATTACHED MODEL VIA ATTACHED MODEL VIA update update OR OR update! update! WITH, WITH, SAY, `@USER.UPDATE!(IMAGES: [ … ] SAY, `@USER.UPDATE!(IMAGES: [ … ] Active Storage has_many_attached attachments get destroyed when subsequent les are attached
  30. Active Storageで使用するActive Jobのqueueが全てのjobで同 じqueueしか指定出来なかったのを、job毎 (con g.active_storage.queues.analysis、 con g.active_storage.queues.purge)に指定出来るよう修正 これにより、元のcon g(con

    g.active_storage.queue)は deprecateになりました DEPRECATE DEPRECATE config.active_storage.queue config.active_storage.queue IN IN FAVOR OF FAVOR OF config.active_storage.queues.analysis config.active_storage.queues.analysis AND AND config.active_storage.queues.purge config.active_storage.queues.purge
  31. ActiveSupport::Noti cations::Eventが保持するデータに、cpu time, idle time, 及びオブジェクトの数を追加 Action Viewのtemplate renderingで表示しているAllocationsはこの値を使 用している

    この対応で時間を取得するのにCLOCK_MONOTONICを使用す るようになったが、これは非互換という事で後ほどrevertされた 最終的に、ActiveSupport::Noti cations.monotonic_subscribeという別のメ ソッドにする事で対応 ADD CPU TIME, IDLE TIME, AND ALLOCATIONS ADD CPU TIME, IDLE TIME, AND ALLOCATIONS FEATURES TO LOG SUBSCRIBER EVENTS FEATURES TO LOG SUBSCRIBER EVENTS Introduce ActiveSupport::Noti cations.monotonic_subscribe
  32. ADD SUPPORT FOR EVENT OBJECT TO THE ADD SUPPORT FOR

    EVENT OBJECT TO THE ACTIVE SUPPORT NOTIFICATION SYSTEM ACTIVE SUPPORT NOTIFICATION SYSTEM # before ActiveSupport::Notifications.subscribe('wait') do |*args| @event = ActiveSupport::Notifications::Event.new(*args) end ActiveSupport::Notifications.instrument('wait') { sleep 1 } @event.duration # => 1000.138 # after ActiveSupport::Notifications.subscribe('wait') { |event| @even ActiveSupport::Notifications.instrument('wait') { sleep 1 } @event.duration # => 1000.138
  33. Date、DateTime、Time、TimeWithZoneにbefore?、afterメソッ ドを追加 それぞれ"<"と">"のエイリアス ADD ADD before? before? AND AND after?

    after? METHODS TO METHODS TO Date Date, , DateTime DateTime, , Time Time, AND , AND TimeWithZone TimeWithZone Date.new(2017, 3, 6).before?(Date.new(2017, 3, 5) Date.new(2017, 3, 6).after?(Date.new(2017, 3, 5)
  34. ADD SUPPORT FOR MULTI ENVIRONMENT ADD SUPPORT FOR MULTI ENVIRONMENT

    CREDENTIALS CREDENTIALS $ EDITOR=vim ./bin/rails credentials:edit -e production Adding config/credentials/production.key to store the encrypti Save this in a password manager your team can access. If you lose the key, no one, including you, can access anythin create config/credentials/production.key Ignoring config/credentials/production.key so it won't end up append .gitignore File encrypted and saved. ./bin/rails credentials:show -e production # aws: # access_key_id: 123 # secret_access_key: 345
  35. env毎のcredentials、及び、keyはcon g/credentialsディレクトリ 配下に生成される envがproductionの場合はproduction.key、及び、production.yml.enc keyを環境変数で指定したい場合は、既存のcredentials同様 RAILS_MASTER_KEYで指定可能(環境変数はenv問わず同じ) なお、credentialファイルは、env毎のcredentialファイル -> 共通 のcredentialファイル(con

    g/credentials.yml.enc)の順で検索 されるようになっており、先に見つかったファイルが使用される 内容のmergeは行われないので、env毎のcredentialファイルが使用される場 合con g/credentials.yml.encはロードされない ADD SUPPORT FOR MULTI ENVIRONMENT ADD SUPPORT FOR MULTI ENVIRONMENT CREDENTIALS CREDENTIALS
  36. rails routesコマンドに結果を縦に表示する為の"--expanded"オ プションを追加 psqlの"--expanded"と同じ形 ADD ABILITY TO SEE THE OUTPUT

    OF ADD ABILITY TO SEE THE OUTPUT OF rails rails routes routes IN EXPANDED FORMAT IN EXPANDED FORMAT ./bin/rails routes --expanded --[ Route 1 ]------------------------------------------------- Prefix | users Verb | GET URI | /users(.:format) Controller#Action | users#index --[ Route 2 ]------------------------------------------------- Prefix | Verb | POST URI | /users(.:format) Controller#Action | users#create
  37. generatorにattachment、attachments eldを指定出来るよう になった Active Storage用の eldで、指定するとmodelへの has_one_attached、又は、has_many_attachedの追加、form への eld_ led等の追加を行ってくれる

    同様に、Action Text用のrich_text eldが追加されている ADD ATTACHMENT AND ATTACHMENTS FIELD ADD ATTACHMENT AND ATTACHMENTS FIELD GENERATORS GENERATORS Add rich_text eld to model generators
  38. Railsで提供しているnpm packages@rails namespace配下に 移動 古いpackageは更新されません MOVE ALL NPM PACKAGES TO

    @RAILS SCOPE MOVE ALL NPM PACKAGES TO @RAILS SCOPE actioncable → @rails/actioncable actiontext → @rails/actiontext activestorage → @rails/activestorage rails-ujs → @rails/ujs