LoginSignup
13
7

More than 3 years have passed since last update.

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

Last updated at Posted at 2017-04-19

問題

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 メソッドの定義を取り消します。

参考

13
7
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
7