Rails の Issue とプルリクを毎日読むと勉強になる

最近やっているけど、これ良い勉強になっているのでブログで紹介する。

読むようになったきっかけ

先月、永和システムマネジメントさんのOSSパッチ会に参加しました。

agile.esm.co.jp

この会の懇親会では Rails の Issue やプルリクの話題が多く出ました。 ただ、私が知らない話題もいくつか出ていて、もっと Rails の更新内容を知りたいと思いました。

その結果、酔った勢いで rails/railsWatching にしてみました。

毎日だけど、雑に読む

Rails は活発に開発されているため、Issue(プルリク)は毎日たくさん増えます。 しかし、これを隅々まで目を通すのはとても大変です。

なので、雑に目を通しています。

  • 興味のないやつは読み飛ばす
    • 自分が使用していない機能(ActionCable, ActiveStorageなど)の Issue やプルリク
  • 英語の長文は Google 翻訳を使って、概要だけ読む
  • 忙しいときはタイトルと description だけ読む
    • コメントを全部読むと時間がかかる

大変だと続かないので、まずは出来る範囲で読んでいます。

雑に Issue やプルリクに目を通すだけであれば、意外と短時間で済みます。

Issue(プルリク) の感想を Twitter に投稿する

  • 便利な機能のプルリクを読んだ
  • 自分の知らなかった Rails の挙動を知った

など、何かあったときは Twitter に投稿してます。

なんとなく、アウトプットしておいた方が記憶に残る気がする。

仕事に役立ちそうな情報は社内に共有する

業務中に Rails の Issue(プルリク) を読む事もあるので、役立ちそうな情報は積極的に社内 Slack に流します。

Rails の最新情報を社内に布教してる」ことを言い訳に、業務中でも Rails の Issue(プルリク)を読みやすくします。*1

2月前半のまとめ

ここ最近で Rails の Issue(プルリク) を読んでいて面白かったのをいくつか紹介する。

リダイレクトの 301, 302 の違い

github.com

  • routes.rbredirect メソッド: 301
  • コントローラの redirect_to メソッド: 302

ステータスコードが違う。

301リダイレクトにはいくつか問題があるので302 を使う方が良いとか、デフォルトの挙動を変えるのはキツいので temporary_redirect を導入するとかの話がされている。

英文が長いので、細かいところは自信ない。

accepts_nested_attributes_for で validates_uniqueness_of が効かない

github.com

一度解決したけど再発したみたい。

Rails 5.2.0.rc1 でも再現する。

p = Parent.create
#=> #<Parent id: 1, created_at: "2018-02-11 18:24:53", updated_at: "2018-02-11 18:24:53">
p.update_attributes :children_attributes => [{:name => "Kid"}, {:name => "Kid"}]
#=> true
Child.all.map(&:name)
#=> ["Kid", "Kid"]
c = Child.first
#=> #<Child id: 1, parent_id: 1, name: "Kid", created_at: "2018-02-11 18:24:59", updated_at: "2018-02-11 18:24:59">
c.save
#=> false
c.errors.full_messages
#=> ["Name has already been taken"]

並列テストのプルリク(WIP)

github.com

rails/rails##26703 で System Test のプルリクを投げた方の新作。

Rails 標準で対応されると便利そう。

has_many through で touch が効かない

github.com

touch が効かないという Issue。
コメントに dependent: :destroy で回避策する方法があるけど、それはどうなんだ...って感じがする。

あと、この Issue で through の対象レコードは削除されないことを知った。マジか。

class Post < ActiveRecord::Base
  has_many :taggings
  has_many :tags, through: :taggings
end

class Tagging < ActiveRecord::Base
  belongs_to :post
  belongs_to :tag
end

class Tag < ActiveRecord::Base
end


post = Post.create!
tag = Tag.create!

post.tags << tag
post.tags.count
#=> 1
post.tags.destroy_all

Tag.count
#=> 1

Tag も消えると思っていました。

Relation#pick の追加

github.com

DHHのプルリクで、 pick ってメソッドが追加されている。

Person.where(id: 1).pick(:name)
  # SELECT people.name FROM people WHERE id = 1 LIMIT 1
  # => 'David'

便利そうだけど、戻り値が文字列 or 配列ってのは気をつけて使わないと NoMethodError が出そう。

あと、このプルリクのテストは最初 fail していて、kamipo さんが「Failing the assert will be fixed by #30000 .」とコメントしていた。 それに対するDHHのコメントは「I just changed the test for now」だった。

「30000をマージして、rebaseにしないのかー」とプルリクを見ながら思った。 まぁ、pick のプルリクのためにマージするにしては 30000 は影響範囲が大きいって判断なのかもしれない。

has_many の関連と where! で誤った値が返ってくる

github.com

where! は内部用のメソッドだから where を使って」とコメントされて close されている。

気になったので Rails 5.2.0.rc1 で試したら再現した。

class User < ActiveRecord::Base
  has_many :tasks
end

class Task < ActiveRecord::Base
end


u = User.create!
2.times { u.tasks.create! }

u.tasks.where(user_id: u.id + 1).count
#=> 0
u.tasks.where!(user_id: u.id + 1).count
#=> 0
u.tasks.where!(user_id: u.id + 1).size
#=> 0
u.tasks.tap { |x| x.where!(user_id: u.id + 1) }.count
#=> 0
u.tasks.tap { |x| x.where!(user_id: u.id + 1) }.size
#=> 2

まとめ

Issue(プルリク)を読んでいると勉強になるので、是非 Rails エンジニアは読んでみると良いですよ。

そして、余裕のある方はプルリクを投げてみよう!*2

*1:まぁ業務中にOSS活動していても特に問題にならないけど

*2:私もまだコントリビュート無いので、2018年は頑張りたい