2014年12月10日水曜日

capistrano3でproduction環境にdeployしたらassets precompileが走らなかった件

railsアプリを作っててcapistrano3でdeployをするようにしていたのですが、
production環境にdeployしたらcssやjsが見れなくて調べたところ、
assets precompileが走ってなかったためでした。
で、なぜassets precompileが走らなかったか調べてみた時のことを書いていきます。

まず、Capfileはこんな感じで、
require 'capistrano/rails/assets'はちゃんと記述していました。
# Load DSL and Setup Up Stages
require 'capistrano/setup'
 
# Includes default deployment tasks
require 'capistrano/deploy'
 
# Includes tasks from other gems included in your Gemfile
#
# For documentation on these, see for example:
#
#   https://github.com/capistrano/rvm
#   https://github.com/capistrano/rbenv
#   https://github.com/capistrano/chruby
#   https://github.com/capistrano/bundler
#   https://github.com/capistrano/rails
#
# require 'capistrano/rvm'
# require 'capistrano/rbenv'
# require 'capistrano/chruby'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
require 'capistrano/bundle_rsync'
require 'capistrano3/unicorn'
 
# Loads custom tasks from `lib/capistrano/tasks' if you have any defined.
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }

deploy/production.rbのserver設定は以下のように書いていました。
server 'host0001', user: 'root', roles: %w{app}

この設定でだめだったので、とりあえずいろいろとGoogle先生で調べてみましたがよくわかりませんでした。
なので、capistranoのソースを読んでみたところ、原因がわかりました。
precompileを実行するためのrolesはwebじゃないと動かないように書いてありました。
capistaranoのコードから抜粋
  namespace :assets do
    task :precompile do
      on roles(fetch(:assets_roles)) do
        within release_path do
          with rails_env: fetch(:rails_env) do
            execute :rake, "assets:precompile"
          end
        end
      end
    end
......
    set :assets_roles, [:web]

なので、deploy/production.rbのserver設定を以下のように変更したところ、ちゃんとprecompileが動くようになりました。
server 'host0001', user: 'root', roles: %w{app web}
完全に無知のためにはまった内容ですが、何かの役に立てばと思って書いてみました。


参考URL
https://github.com/capistrano/rails/blob/5f112183dad808078a56c8558046d84d182eddf6/lib/capistrano/tasks/assets.rake

2014年12月3日水曜日

railsでcsvダウンロードできるようにしたらexcelで文字化けした件

データをcsvでダウンロードしたいって要望があったので、
railsでcsvダウンロード機能を作ったら、excelで開いたら文字化けするって言われた時の対応です。

バージョンは以下で試しました。
ruby 2.1.2
rails 4.1.5

まず最初に書いたcsvダウンロード部分を抜粋。
ローカルにファイルを出力して、それをsend_fileで返す形です。
  filename = '/tmp/test.csv'
  line = ['aa','bb','cc']
  open(filename,"w"){|f|
    f.puts(line.join(','))
  }
 
  stat = File.stat(filename)
  send_file(filename, :filename => 'test.csv', :length => stat.size)
この形だとファイルの文字コードがUTF-8になります。
UTF-8だとexcelで開いた時には文字化けしました。
(Libre Officeだと最初にencodeをどれにするか聞かれたので、UTF-8にすれば問題なく開けました。)

最初の処理から文字コードを変えた形。
  filename = '/tmp/test.csv'
  line = ['aa','bb','cc']
  open(filename,"w:cp932"){|f|
    f.puts(line.join(','))
  }
 
  stat = File.stat(filename)
  send_file(filename, :filename => 'test.csv', :length => stat.size)
ローカルにファイルを出力するタイミングで
文字コードの指定を「cp932」にしてあげると、
文字化けせずにexcelで開けるようになりました。
macのexcelでもUTF-8だと文字化けしたのが、excelがっかりだなぁと思ったりした次第です。

参考URL
http://tmtms.hatenablog.com/entry/20120812/ruby_encoding