Capistranoでデプロイした時にunicornが再起動しなかった話
capistranoを使用し、ec2にデプロイした時に
Bundler::GemfileNotFound
というエラーが出てしまい、unicornの再起動がうまくいかない時の対処法。
Gemfileは存在しているのだが、
Gemfile読み取り時に過去のバージョンのディレクトリのGemfileを見ようとし
そのディレクトリはすでに存在しないので、エラーが起きてしまう。
config/unicorn/production.rbまたはstaging.rbに以下を記述
before_exec do |server| ENV['BUNDLE_GEMFILE'] = "ec2内のGemfileまでのパス" end
すでにこの問題が起きてしまっている場合は、
再度デプロイしても失敗してしまうので、
一度、unicornを手動で停止または、再起動しなくてはならない。
railsでgooglemapを表示
Gemfileに以下を追加して、bundle install
gem 'gmaps4rails' gem 'geocoder'
application.html.slimのhead内に以下を記述
script src="//maps.google.com/maps/api/js?v=3.23&key=[API_KEY]"
script src="//cdn.rawgit.com/mahnunchik/markerclustererplus/master/dist/markerclusterer.min.js"
script src='//cdn.rawgit.com/printercu/google-maps-utility-library-v3-read-only/master/infobox/src/infobox_packed.js' type='text/javascript'
[API_KEY]には、Google Maps APIのキーを取得して入れてください
以下urlより
Get API Key | Google Maps JavaScript API | Google Developers
application.jsに以下を追加
//= require gmaps/google //= require underscore
underscore.jsはこちらからコピーし
http://underscorejs.org/underscore-min.js
app/assets/javascript/underscore.jsに記述
googlemapを表示したいview側に以下を追加
#map style="width: 800px; height: 400px;"
javascript: handler = Gmaps.build('Google'); handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){ markers = handler.addMarkers(#{raw @hash.to_json}); handler.bounds.extendWith(markers); handler.fitMapToBounds(); });
controller側に以下を記述
@places = Place.all address = 住所 lati_long = Geocoder.coordinates(address) @hash = Gmaps4rails.build_markers(@places) do |place, marker| marker.lat lati_long[0] marker.lng lati_long[1] end
Geocoder.coordinates(address)のaddress部分に住所を入れると
緯度と経度を取得してくれます。
railsで検索可能なセレクトボックスを実装
select2-railsというgemを使用し、
検索可能なセレクトボックスを作成することができます。
Gemfileに以下を記述してbundle installを実行。
gem 'select2-rails'
application.jsに以下を追加
//= require select2
application.cssに以下を追加
*= require select2
select2を使用したいところに、以下のjsを追加
$('フォームのidまたはclass').select2({ width: 400, allowClear: true });
allowClear: trueをつけると、
×ボタンでセレクトボックスで選択したものを削除できる。
allowClear: trueがうまく動かなかったので
以下jsを追加して、無理やり動かした
$('.select2-selection__clear').on('click', function(){
$('フォームのidまたはclass').val(null).trigger("change");
})
meta_tagsでrailsのSEO対策
Railsで、no_indexを使ったり、titleをページごとに変えたいというときがあると思うのですが、その時にmeta_tagsというgemが役に立ちます。
Gemfile
に以下を記述してbundle install
を実行
gem 'meta_tags'
helpers/application_helper.rbに以下を記述
def default_meta_tags
{
title: "サイトのタイトル",
description: "説明",
keywords: "キーワード",
icon: image_url("サイトのアイコン"),
charset: "UTF-8",
og: {
title: "タイトル",
type: "website",
url: request.original_url,
image: image_url("OGPで設定する画像"),
site_name: "サイト名",
description: "説明",
locale: "ja_JP"
}
}
end
OGPはサイトのURLを貼った時に表示されるやつです。
layouts/application.html.slimのheadに以下を追加
= display_meta_tags(default_meta_tags)
これでデフォルトで設定したmeta_tagを読み込みます。
特定のページをno_indexにしたいという場合は
該当ページのviewに以下を記述します
- set_meta_tags noindex: true
ページのタイトルを変えたい場合は
該当ページのview側に以下を記述
- set_meta_tags title: "タイトル"
ページタイトル | デフォルトで設定したタイトルのように
したい場合は以下のように記述
- set_meta_tags site: "タイトル"
Railsでアニメーションを使ったページネーションがしたかった話
ページの切り替え時にアニメーションを使い
ページを切り替えるということがしたかったのでまとめ
Gemfile
に以下を記述し、bundle install
します。
gem 'kaminari'
kaminari自体でも、ページネーションは可能ですが、
今回は、一部の機能だけを使用します。
ページネーションをしたいだけであれば、普通にkaminariを使うことをオススメします。
controllerに、以下を記述。
def index @books = Book.page(params[:page]).per(5) end
page(params[:page])
で現在のページを取得し、対応したBookを取り出しています。
pre(5)
は、デフォルトの表示数を表しています。何もない場合は25表示されます。
また、対応モデルに以下を記述することで、デフォルト値を変更することも可能です。
paginates_per 10
ページネーションを使いたいだけなら
controllerに記述後、ビュー側に以下を記述すれば、ページネーションは完成します。
= paginate @books
今回、= paginate
は使用しません
ページネーションしたいところを、部分テンプレートにします
index.html.slim
に以下を記述。
#books
=render partial: 'book'
_book.html.slim
に以下を記述。
-unless @books.first_page? =link_to '<', books_path(page: @books.prev_page), remote: true -@books.each do |book| =book.title -unless @books.last_page? =link_to '>', books_path(page: @books.next_page),remote: true
first_page?
で最初のページかどうか、
last_page?
で最後のページかどうかを判断し
prev_page
next_page
でそれぞれ、
前のページと次のページに飛ばす処理をしています。
部分テンプレートだけを更新したいので、
remote: true
を使用し、Ajax処理をします。
最後に、index.js.erb
に以下を記述し、ページ切り替え時にアニメーションを使用します。
$('#books').fadeOut(300); function openPage(){ $('#books').html("<%= j (render 'book') %>"); $('#books').fadeIn(500); } setTimeout("openPage()", 300);
railsでcrontab実装
wheneverというgemを使うことで、
定期的にcronで実行したいバッチ処理等を簡単に作成できます。
Gemfile
に以下を記述してbundle install
を実行
gem 'whenever', require: false
その後、次のコマンドを実行
bundle exec wheneverize .
すると、config
以下にschedule.rb
が作成されます。
次の4つをスケジューリングできます。
command: bashコマンドの実行 rake: rakeタスクの実行 runner: Rails内のメソッド実行 script: scriptの実行
次にschedule.rb
に設定を記述します。
# ログファイルの指定 set :output, "#{path}/log/cron.log" #実行環境の指定(デフォルトはproduction) set :environment, :production every 1.day, at: '6:00 am' do runner 'MyModel.test' end
毎日am6:00にMymodelのtestメソッドが実行されます。
他にも設定方法は色々あり、少し例をあげると
#1時間ごと :hour #3時間ごと 3.hours #曜日指定 :sunday, at: '6am' #毎月25~30日まで、0:00に実行 '0 0 25-30 * * '
こんな感じです。
wheneverでは、Rails.root
が使えないらしいので、
Rails内のディレクトリを参照する場合は#{path}
をつけてください。
最後に、crontabの設定です。
#crontabの設定、更新 RAILS_ENV=development bundle exec whenever --update-crontab #crontabの設定削除 RAILS_ENV=development bundle exec whenever --clear-crontab
FTPサーバーからファイルを取得する(Ruby)
まず、FTPサーバーを構築します。
今回は、ローカル(Mac)とAzureに構築する二つのパターンを紹介します。
・ローカルでFTPサーバーを立ち上げる
起動する。
sudo launchctl load -w /System/Library/LaunchDaemons/ftp.plist
停止する。
sudo launchctl unload -w /System/Library/LaunchDaemons/ftp.plist
これだけです。
・AzureでFTPサーバーを立ち上げる
Azureにログイン後、新規->Web+モバイル->WebAppと選択し、
アプリ名やサブスクリプションなどを入力し作成。
サーバー構築後、設定->デプロイ資格情報でユーザ名とパスワードを設定します。
設定->プロパティでFTPホスト名が分かるのでFTPクライアントからAzureサーバーへ接続を行うことができます。
・FTPサーバーからファイルを取得する
require 'net/ftp'
host = URI(FTPホスト名).host
port = URI(FTPホスト名).port
remotefile = '習得するFTP側のファイルのフルパス'
local_file = '習得したデータの保存ファイルのフルパス'
#localの場合
Net::FTP.open('localhost') do |ftp|
ftp.login(ローカルのユーザ名, ローカルのパスワード)
ftp.passive = true
ftp.get(remotefile, local_file)
end
#Azureの場合
ftp = Net::FTP.new
ftp.connect(host, port)
ftp.login(Azureに設定したユーザ名, Azureに設定したパスワード)
ftp.passive = true
ftp.get(remotefile, local_file)