Ruby
Rails

Rails で open という emum を定義した場合に、メソッドの上書きに対する警告を取り除く

More than 1 year has passed since last update.


問題

class Ticket < ApplicationRecord

enum status: {
open: 1,
closed: 2
}
end

上記の Ticket モデルでは、status カラムに Rails の enum を使っています。enum を定義すると、自動的に open, closed という名前のスコープも定義されます。

Ticket.open.to_sql #=> SELECT "tickets".* FROM "tickets" WHERE "tickets"."status" = 1

Ticket.closed.to_sql #=> SELECT "tickets".* FROM "tickets" WHERE "tickets"."status" = 2

この open という名前が少し曲者です。モデルのクラスには Kernel から継承した open という名前のプライベートメソッドが既に存在します。

pry(main)> $ Ticket.open

From: /Users/quanon/.rbenv/versions/2.3.4/lib/ruby/2.3.0/open-uri.rb @ line 29:
Owner: Kernel
Visibility: private
Number of lines: 11

def open(name, *rest, &block) # :doc:
if name.respond_to?(:open)
name.open(*rest, &block)
elsif name.respond_to?(:to_str) &&
%r{\A[A-Za-z][A-Za-z0-9+\-\.]*://} =~ name &&
(uri = URI.parse(name)).respond_to?(:open)
uri.open(*rest, &block)
else
open_uri_original_open(name, *rest, &block)
end
end

そのせいで、クラスの読み込み時に

Creating scope :open. Overwriting existing method Ticket.open.

という警告が表示されてしまいます。


解決策

class Ticket < ApplicationRecord

class << self; undef :open; end

enum status: {
open: 1,
closed: 2
}
end

enum を定義する前に undef を使って open メソッドの定義を取り消します。


参考