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

Rails5.0 (Ruby2.3,2.4)新機能勉強会20180525

Rails5.0 (Ruby2.3,2.4)新機能勉強会20180525

Rails5.0 (Ruby2.3,2.4)の主な新機能を紹介したスライド

m_okamoto

May 25, 2018
Tweet

Other Decks in Programming

Transcript

  1. 1. belongs_toのrequiredがデフォルトでtrueに DemoA:親テーブル • required: true ⇒nilを許容しない(Rails5.0のデフォルト) • required: false

    ⇒nilを許容する (Rails4.xのデフォルト) 5.0 class DemoA < ActiveRecord::Base end class DemoB < ActiveRecord::Base belongs_to :demo_a #optional 未指定 end DemoA.inspect #=> “DemoA(id: integer, name: string)“ DemoB.inspect #=> “DemoB(id: integer, demo_a_id: integer)“ DemoB.create.inspect (0.2ms) BEGIN (0.2ms) ROLLBACK #=> "#<DemoB id: nil, demo_a_id: 0>" DemoB:子テーブル Create失敗!!
  2. 1. belongs_toのrequiredがデフォルトでtrueに DemoA:親テーブル • required: true ⇒nilを許容しない(Rails5.0のデフォルト) • required: false

    ⇒nilを許容する (Rails4.xのデフォルト) 5.0 class DemoA < ActiveRecord::Base end class DemoB < ActiveRecord::Base belongs_to :demo_a, optional: true end DemoA.inspect #=> “DemoA(id: integer, name: string)“ DemoB.inspect #=> “DemoB(id: integer, demo_a_id: integer)“ DemoB.create.inspect (0.2ms) BEGIN SQL (0.5ms) INSERT INTO `demo_bs` VALUES () (0.2ms) ROLLBACK #=> "#<DemoB id: 1, demo_a_id: 0>" DemoB:子テーブル Create成功!!
  3. 2. ActionController::ParametersがHashを継承しない Rails4 # ActionController::Parameters class Parameters < ActiveSupport::HashWithIndifferentAccess #

    ActiveSupport::HashWithIndifferentAccess class HashWithIndifferentAccess < Hash # ActionController::Parameters class Parameters Rails5 • Hashにしかないメソッドは使えない 5.0
  4. 3. nil でもメソッド呼び出しがエラーにならない safe navigation operator(ぼっちオペレーター) • オブジェクトが nil でもエラーを恐れずメソッドが呼び出せる

    • &.はrubyのオペレータなので、メソッドコールであるtry!よりも速い • ぼっちオペレーターが主流 nil.try(:book) #=> nil nil.try!(:book) #=> nil nil&.book #=> nil "foo".try(:book) #=> nil "foo".try!(:book) NoMethodError: undefined method 'book' for "foo":String "foo"&.book NoMethodError: undefined method 'book' for "foo":String Ruby 2.3
  5. 4. Fixnum,BignumクラスがIntegerクラスに統合 • Ruby2.3までは整数は基本的にFixnumクラスで、極端に大きいまたは 小さい数になるとBignumクラス • Ruby 2.4では両者の親クラスであるIntegerクラスに統合 • Fixnum

    , Bignum はdeprecated #ruby 2.3 1.class #=> Fixnum -1.class #=> Fixnum 10000000000000000000000000000.class #=> Bignum -10000000000000000000000000000.class #=> Bignum #ruby 2.4 1.class #=> Integer -1.class #=> Integer 10000000000000000000000000000.class #=> Integer -10000000000000000000000000000.class #=> Integer Ruby 2.4
  6. 2. クエリ関連のメソッド追加 (#or, #left_outer_joins, #left_joins) User.where(id:1).or(User.where(id:2)) User Load (0.6ms) SELECT

    `users`.* FROM `users` WHERE ((id = 1) OR (id = 2)) #=> #<ActiveRecord::Relation [#<User id: 1,・・・>, #<User id: 2,・・・>]> Author.left_outer_joins(:books) Author Load (0.3ms) SELECT "authors".* FROM "authors“ LEFT OUTER JOIN "books" ON "books"."author_id" = "authors"."id“ #=> #<ActiveRecord::Relation [#<Author id: 1, name: "Mark" ,・・・> or : OR条件指定 left_outer_joins : 外部結合 5.0
  7. 3. Enumerableモジュールに#pluckと#withoutが追加 [{ name: "David" }, { name: "Rafael" },

    { name: "Aaron" }].pluck(:name) #=> ["David", "Rafael", "Aaron"] people = ["David", "Rafael", "Aaron", "Todd"] people.without "Aaron", "Todd“ #=> ["David", "Rafael"] • RailsでRubyの拡張 • Pluck : 特定のレコードのカラムを配列にする • Without : 配列の中から特定の要素を除く 5.0
  8. 4. ActiveRecord::Relation#in_batchesメソッドが追加 User.in_batches.class #=> ActiveRecord::Batches::BatchEnumerator User.in_batches.update_all(verified: true) User.in_batches.each do |relation|

    relation.class #=> User::ActiveRecord_Relation relation.update_all(verified: true) sleep 10 end • find_in_batches:ブロックの引数がArray • in_batches:ブロックの引数がActiveRecord::Relation 5.0
  9. 1. 合致しない要素を返す Enumerable#grep_v • grepコマンドの-vオプションと同等の役割 list = %w(foo bar baz)

    #=> ["foo", "bar", "baz"] list.grep_v(/ba/) #=> ["foo"] list.grep(/ba/) #=> ["bar", "baz"] Ruby 2.3
  10. 2. 複数の値をまとめてfetchする Hash#fetch_values • 該当のキーが検出された場合のみ、キーに対する値の配列を返す • 値が無かった場合、values_atはnilを返すのに対して、 fetch_valuesは例外KeyErrorを返す h =

    { foo: 1, bar: 2, baz: 3} #=> {:foo=>1, :bar=>2, :baz=>3} h.fetch_values(:foo, :bar) #=> [1, 2] h.values_at(:foo, :none) #=> [1, nil] h.fetch_values(:foo, :none) KeyError: key not found: :none Ruby 2.3 Ruby 2.3
  11. 3. 数値の正負を判別する Numeric#positive?, #negative? • positive? : 数値が正の値の場合 true、それ以外なら false

    • negative? : 数値が負の値の場合 true、それ以外なら false 1.positive? #=> true -1.positive? #=> false 1. negative? #=> false -1.negative? #=> true Ruby 2.3
  12. 6. ヒアドキュメント内のインデントを 取り除いてくれる <<~ (squiggly heredoc) • Rubyのヒアドキュメント<<-を使うと、ヒアドキュメント内のインデ ントはそのままスペースやタブとして残っていた •

    <<~を使うとstrip_heredoc と同様に、ヒアドキュメント内のインデ ントを取り除いてくれる # <<- を使うと、ヒアドキュメント内のインデントがそのままスペースとして残ってしまう text_with_legacy_heredoc = <<-TEXT This would contain specially formatted text. That might span many lines TEXT " This would contain specially formatted text.¥n That might span many lines¥n“ Ruby 2.3
  13. 6. ヒアドキュメント内のインデントを 取り除いてくれる <<~ (squiggly heredoc) # Railsのstrip_heredocを使うと、インデントのスペースを取り除くことができる text_with_strip_heredoc =

    <<-TEXT.strip_heredoc This would contain specially formatted text. That might span many lines TEXT "This would contain specially formatted text.¥nThat might span many lines¥n“ # <<~ を使うとstrip_heredocと同じようにインデントのスペースを取り除いてくれる text_with_squiggly_heredoc = <<~TEXT This would contain specially formatted text. That might span many lines TEXT => "This would contain specially formatted text.¥nThat might span many lines¥n" Ruby 2.3
  14. 2. 切り上げ、切り下げ、切り捨てで小数点の 位置を指定できるようになった • ceil、floor、truncateの各メソッドに引数を渡して、切り上げ、切り下げ、 切り捨てを行う小数点の位置を指定 • デフォルトは一の位に対して実行 # 切り上げ

    1.11.ceil #=> 2 1.11.ceil(1) #=> 1.2 -1.11.ceil #=> -1 -1.11.ceil(1) #=> -1.1 11111.ceil(-1) #=> 11120 # 切り下げ 1.99.floor #=> 1 -1.99.floor #=> -2 1.99.floor(1) #=> 1.9 # 切り捨て 1.99.truncate #=> 1 -1.99.truncate #=> -1 1.99.truncate(1) #=> 1.9 Ruby 2.4
  15. 5. MatchData#values_atで名前付きキャプチャの 名前を指定できるようになった • Ruby 2.3までは指定できるのは、キャプチャした文字列のインデックスだけ • Ruby 2.4では名前付きキャプチャの名前を指定できるように m

    = /(?<year>¥d+)-(?<month>¥d+)-(?<day>¥d+)/.match('2018-05-01’) #=>#<MatchData "2018-05-01" year:"2018" month:"05" day:"01"> m.values_at(1, 3) #=> ["2018", "01"] m.values_at('year', 'day’) #=>["2018", "01"] m.values_at(:year, :day) #=> ["2018", "01"] Ruby 2.4
  16. 6. 指定した条件で重複をなくすEnumerable#uniq • 配列だけでなく、ハッシュでもuniqが使えるように • 引数にvalueを指定することでvalueでuniqできる olimpics = { 1896

    => 'Athens’, 1900 => 'Paris’, 1904 => 'Chikago’, 1906 => 'Athens’, 1908 => 'Rome’ } #=>{1896=>"Athens", 1900=>"Paris", 1904=>"Chikago", 1906=>"Athens", 1908=>"Rome"} olimpics.uniq { |k, v| v } #=> [[1896, "Athens"], [1900, "Paris"], [1904, "Chikago"], [1908, "Rome"]] Ruby 2.4
  17. 7. concatメソッドが複数の配列を引数に取れるように [1, 2].concat([3, 4], [5, 6]) => [1, 2,

    3, 4, 5, 6] 8. concatメソッドとprependメソッドが複数の文字列を 受け取れるように 'a'.concat('b','c’) #=> "abc“ 'z'.prepend('x','y’) #=> "xyz" Ruby 2.4
  18. 10. ディレクトリやファイルが空かどうかを判定する Dir.empty?、File.empty? • File.empty?は以前からあったFile.zero?のエイリアス require 'tmpdir’ Dir.mktmpdir { |dir|

    Dir.empty?(dir) } #=> true IO.write("zero.txt", "") File.zero?("zero.txt") #=> true IO.write("nonzero.txt", "1") File.zero?("nonzero.txt") #=> false IO.write("zero.txt", "") File.empty?("zero.txt") #=> true IO.write("nonzero.txt", "1") File.empty?("nonzero.txt") #=> false Ruby 2.4
  19. 11. プログラムの実行中にirbが開けるbinding.irb メソッドの追加 • binding.pryのirbバージョン • デバッグの際などに使える [binding_irb.rb] require 'irb’

    s = 'hello’ puts s # ここでirbを開く binding.irb puts s puts 'bye’ $ ruby binding_irb.rb hello irb(main):001:0> s "hello" irb(main):002:0> s = "modify" "modify" irb(main):003:0> exit modify bye Ruby 2.4
  20. 公式情報 Rails5.0 • CHANGELOG | rails/rails/*/CHANGELOG • Ruby on Rails

    5.0 Release Notes | RAILS GUIDES • Ruby on Rails 5.0 リリースノート | RAILS GUIDES (日本語) Ruby2.3 • https://github.com/ruby/ruby/blob/ruby_2_3/NEWS Ruby2.4 • https://github.com/ruby/ruby/blob/v2_4_0/NEWS Rails SQL Injection • https://rails-sqli.org/rails5
  21. Logger.newのキーワード引数追加 • Logger.newのキーワード引数としてlevel、progname、formatter、 datetime_formatが追加 require 'logger’ formatter = proc {

    |severity, timestamp, progname, msg| "#{severity}:#{msg}¥n¥n" } logger = Logger.new( STDERR, level: :info, progname: :progname, formatter: formatter, datetime_format: "%d%b%Y@%H:%M:%S“ ) logger.level => 1 logger.level == Logger::INFO => true logger.progname => :progname logger.formatter => #<Proc:0x00007f1053d99c60@(irb):66> logger.datetime_format => "%d%b%Y@%H:%M:%S" Ruby 2.4
  22. optparseで起動時引数をハッシュに格納するintoオプション • optparseで起動時引数をパースする際、intoオプションを使ってパースした 結果をハッシュに格納できる cli = OptionParser.new do |options| options.define

    '--from=DATE', Date options.define '--names=LIST', Array end config = {} args = %w[ --from 2016-02-03 --names John,Daniel,Delmer ] cli.parse(args, into: config) config.keys => [:from, :names] config[:from] => #<Date: 2016-02-03・・> config[:names] => ["John", "Daniel", "Delmer"] Ruby 2.4
  23. テキストファイルを行単位で読み込む際に、chompするか どうかを指定できるようになった • IO#gets, IO#readline, IO#each_line, IO#readlines, IO#foreachでchomp オプションを指定可能に •

    最初からchomp (改行文字を削除)した状態で各行のテキストを取得できる File.write("text", "abc¥nxyz¥r¥n") IO.readlines("text") ["abc¥n", "xyz¥r¥n"] IO.readlines("text", chomp: true) => ["abc", "xyz"] Ruby 2.4
  24. ハッシュの値を特定のルールで変更する Hash#transform_values • ハッシュの値を特定のルールで変更できる • 破壊的な変更を行うtransform_values!メソッドもある x = {a: 1,

    b: 2, c: 3} y = x.transform_values {|v| v ** 2 } => {:a=>1, :b=>4, :c=>9} x => {:a=>1, :b=>2, :c=>3} y = x.transform_values! {|v| v ** 2 } => {:a=>1, :b=>4, :c=>9} x => {:a=>1, :b=>4, :c=>9} Ruby 2.4
  25. ハッシュにcompact/compact!メソッドが追加された • Valueがnilのものを除外 hash = { a: 1, b: nil,

    c: 2 } {:a=>1, :b=>nil, :c=>2} hash.compact {:a=>1, :c=>2} hash {:a=>1, :b=>nil, :c=>2} hash.compact! {:a=>1, :c=>2} hash => {:a=>1, :c=>2} Ruby 2.4