24
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[Rails] partialが自身からの相対パスで他partailを参照する場合の注意

Last updated at Posted at 2017-11-21

先日、仕事中に少し嵌ったpartialの振る舞いについてまとめます。

環境

Rails 5.1.4

内容

例えば、以下のようなディレクトリ構成のViewがあるとします。
もちろん、Controllerとcofig/routes.rbは適切に設定されています。

view/
├── layouts/
└── test/
    ├── index.html.haml
    ├── _child.html.haml
    └── _grandson.html.haml
app/view/test/index.html.haml
= render partial: 'child'
app/view/test/_child.html.haml
= render partial: 'grandson'
app/view/test/_grandson.html.haml
%p hoge from test

/testにアクセスすれば、当然、hoge from testと表示されます。この振る舞いについては自然に思われます。
次にTest2Controller.rbを作成し、以下のようにindex.html.hamlを追加します。

view/
├── layouts/
├── test/
│   ├── index.html.haml
│   ├── _child.html.haml
│   └── _grandson.html.haml
└── test2/
    └── index.html.haml
app/view/test2/index.html.haml
= render partial: 'test/child'

この様な場合も、hoge from testと表示されるものと私は期待したのですが、実際には以下のようなエラーになりました。

Missing partial test2/_grandson, application/_grandson with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :ts, :haml, :jbuilder]}. Searched in:
  * "/#{アプリケーションのディレクトリ}/app/views"

これをみるとtest/_grandsonではなく、test2/_grandsonを見にいってしまっていることがわかります。
そこで、以下のファイルを追加すると、

app/view/test2/_grandson.html.haml
%p hoge from test2

hoge from test2と表示されます。
つまり、相対パスの基準はpartialのディレクトリではなく、呼出元のhamlがあるディレクトリに依存するというわけです。
test2でも test/_grandsonをみるようにするためには、view/からの相対パスで書けばよいです。

app/view/test/_child.html.haml
= render partial: 'test/grandson'

結論

view/からの相対パスで書くのが安全かもしれません。
(view/からの相対パスで書かないのはバッドプラクティスといえるほど経験を積んでいないので、可能性の示唆に留めて置きます。そういう言明があれば教えていただきたいです。)

24
17
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
24
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?