Rails の個別スタイルシート呼び出しをもうちょっといい感じにする

例えば WelcomeController の index アクションが呼ばれた場合、デフォルトの状態だとビューには welcome.css(.scss) がロードされるのだけど、これを呼ぶかどうかについて、ファイルの有無とか controller での変数で判定できたらいいのになという話。

色々方法はあるかと思うのですが、以下のようにしてみました。

assets/stylesheets/application.css

 *= require_self
 *= require_directory . 

デフォルトだと require_tree . となっている箇所を require_directory . にする。こうすることでルートディレクトリ( assets/stylsheets/* )の css しか自動でインポートしないようにする。

ついでにスタイルシートのディレクトリも以下のように views っぽくする。

f:id:ltcmdr927:20121209105229p:plain

HEAD タグは application.html.erb で編集しているので、そこを修正する。

views/layouts/shared/application.html.erb

  <%= stylesheet_link_tag "application", :media => "all" %>
  <%= partial_stylesheet_link_tag controller.controller_name, controller.action_name, @partial_css_disabled %>
  <%= javascript_include_tag "application" %>

stylesheet_link_tag と javascript_include_tag の間に新しい helper メソッドを追加する。引数でビューを読んだ時のコントローラ名とアクション名を指定。@partial_css_disabled は後述。

app/helpers/application_helper.rb

module ApplicationHelper
  
  def partial_stylesheet_link_tag(controller_name, action_name, disabled = true)
    if disabled == false || disabled.nil?
      if File.exist?("#{Rails.root.to_s}/app/assets/stylesheets/#{controller_name}/#{action_name}.css.scss")
        return stylesheet_link_tag "#{controller_name}/#{action_name}"
      end
    end
  end
  
end

partial_stylesheet_link_tag メソッドを書く。disabled が false かあるいは nil かを判定し、正なら scss ファイルの有無を判定し、最終的にコントローラ/アクションの stylesheet_link_tag を戻す、という感じ。

基本的にはファイルの有無で stylesheet タグが追加されるかどうかを判定するようになるので、例えばファイルは存在するけどタグは追加したくないという場合は、下記のように controller で @partial_css_disabled 変数に true を指定してやる。 true を指定するとファイルが存在していてもタグが追加されない。

app/controller/welcome_controller.rb

class WelcomeController < ApplicationController
  
  def index
    @partial_css_disabled = true
  end
  
end

若干イモっぽい感じがしなくもないですが、個人的にはこれで管理しやすくなりました。(コントローラの階層構造が深くなった場合については調査して後々追記予定。)