LoginSignup
3
2

More than 5 years have passed since last update.

models/concerns/hoge.rb と controllers/concerns/hoge.rbを作ると、死ぬ可能性がある。

Last updated at Posted at 2016-01-28

死んでいたので。

concernsという、その他諸々みたいなものを入れておくディレクトリがある。

models/concerns/hoge.rbでmoduleを定義する

#models/concerns/hoge.rb

module Hoge
    def hoge
        ' hoge by concern in models'
    end
end

そして、controllers/concerns/hoge.rbでmoduleを定義する。

#controllers/concerns/hoge.rb

module Hoge
    def hoge
        ' hoge by concern in controllers'
    end
end

そして、どっかのmodelでHogeをincludeする。
すると直感的には、models/concerns/hoge.rbが読まれてほしい。
つまり以下は

#models/fuga.rb

class Fuga
    include Hoge
    def hello
        "hello" + hoge
    end
end

こうなってほしい

> Fuga.new.hello => "hello hoge in concern in models"

しかし、実際は。。。

> Fuga.new.hello => "hello hoge by concern in controllers

controllers/concerns/hoge.rbが呼ばれている。

これは、railsがincludeするときにファイルを探すとき、module名に対応したファイルを探すらしい。その時に、modelsのディレクトリよりもcontrollersを先に読んでしまう。
なので、controller側のhoge.rbを読んで終わってしまう。

この時気をつけなれければならないのは、じゃあcontrollerの方を適当に入れ子にしておけばいいと思うこともあるかもしれない。以下のような感じ。(僕はこれで行けると思ってしまいました)

#controllers/concerns/hoge.rb

module ControllerHoge
    module Hoge
        def hoge
            ' hoge by concern in controllers'
        end
    end
end

するとこんなエラー。

LoadError: Unable to autoload constant Hoge, expected /home/vagrant/src/stocker/app/controllers/concerns/hoge.rb

要するに、railsはcontrollerのconcernでincludeしたmodule名に対応したファイルを見つけると(Hogeに対してhoge.rb) そのファイルを読み込んでしまう。
そこでファイルの中を見てみると、module Hoge がないやでと言われてしまう。というわけだ。

タイトルに出した「死ぬ」はこれ。僕はこれでうわぁぁぁってなってました。

でもこういった感じで同じファイル名を与えたいときはあると思う。

なので、こうすることですっきりした。(つもり)

まず controllers/concerns/somedir を作る。
そしてディレクトリに対応してネームスペースを与える。

#controllers/concerns/somedir

module Somedir::Hoge
    def hoge
        'hoge by concern in controller'
    end
end

そして、Fuga.new.helloを実行。

> Fuga.new.hello => "hello hoge by concern in models"

いやぁ。。。仕様をもっと理解しよう。

3
2
0

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
3
2