godでThe server is not available (or you do not have

色々と設定をいじっていて、godのプロセスが立ち上がらなくなった。

1
2
rbenv exec bundle exec god terminate
# => The server is not available (or you do not have permissions to access it)

多分rootとかで色々やった時に出きたpidファイルとかが悪さしてるんだろうなー。
って思ったけどどこにあるのか?

とりあえずRAILS _ROOTのtmpを見てみるけど。ない

軽くはまりつつも、/tmpにありました。
/tmp/god.12223.sock

コレを消して無事解決!


jQueryのappendが重かったので対応したこと

railsでチェックボックスで会社を選択して、ajax通信で返すjsの内容がこんな感じだった。

1
2
3
4
5
  <% @company.each do |company| %>
    <% company.member.each do |customer| %>
        $("#customer_area").append("<%= escape_javascript(render("make_customer_area", cid: customer.id)) %>");
    <% end %>
  <% end %>

重い。console.time仕込んで計測したらappendがめちゃめちゃ重い。
一回のappendで1秒ぐらいかかってた。

毎回appendじゃなくて、一回でappendしてみる

1
2
3
4
5
6
7
8
9
10
11
  var html = []
  var customer_area = $("#customer_area")
  <% @company.each do |company| %>
    <% company.member.each do |customer| %>
        html.push("<%= escape_javascript(render("make_customer_area", cid: customer.id)) %>");
    <% end %>
  <% end %>

  if ( html.length > 0 ){
    customer_area.append(html.join(''))
  }

あんまり変わらないなぁ。
というかappendやめよ。もうやめよ。

1
2
3
4
5
6
7
8
9
10
11
  var html = []
  var customer_area = document.getElementById("customer_area");
  <% @company.each do |company| %>
    <% company.member.each do |customer| %>
        html.push("<%= escape_javascript(render("make_customer_area", cid: customer.id)) %>");
    <% end %>
  <% end %>

  if ( html.length > 0 ){
    customer_area.innerHTML = customer_area.innerHTML + html.join('')
  }

約0.5秒ぐらい早くなった。いいね。
でもinnnerHTML使ってるから、何回か会社をクリックするとinnerHTMLにテキストが溜まりすぎてだんだん重くなる。
innnerHTML参照せずにappendChildで追加しよう。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  var html = []
  var customer_area = document.getElementById("customer_area");
  <% @company.each do |company| %>
    <% company.member.each do |customer| %>
        html.push("<%= escape_javascript(render("make_customer_area", cid: customer.id)) %>");
    <% end %>
  <% end %>

  if ( html.length > 0 ){
    var element = document.createElement('div');
    element.innerHTML = html.join('');
    customer_area.appendChild(element);

  }

これで当初の半分ぐらいまでは処理時間が軽減されました。


knexで外部キー制約のマイグレーション

Node.js向けORM Bookshelfの紹介を参照させていただきながら、Bookshelf触ってみている。

ページではsqlite3だけど、自分はmysqlで使っている。

外部キー制約の部分。

1
 t.integer('post_id').notNull().references('id').inTable('posts');

がmysqlではCannot add foreign key constraintが出て動かなかった。

これで動いた。

1
t.integer('post_id').unsigned().notNullable().references('id').inTable('posts');

csvからuserを検索して、データ更新サンプル

例えば外部システムとユーザの情報を持ち合っている時。
外部システムのuser id(コード内ではuser external _id)から、システム内のユーザIDを導き出して、そのデータにパッチを当てるスクリプト。

active _recordとかは単品で扱ってる(database.yml'読み込み)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#!/usr/bin/env ruby
# coding: utf-8
require 'csv'
require 'optparse'
require "active_record"

params = ARGV.getopts('', 'csv:user.csv', 'ENV:development', 'RAILS_ROOT:./')
p params

config = YAML.load_file( params['RAILS_ROOT'] + 'config/database.yml' )
raise ArgumentError, 'ENVが設定されていません'            if params['ENV'].nil?
raise ArgumentError, 'RAILS_ROOTが指定されていません'     if params['RAILS_ROOT'].nil?
raise ArgumentError, 'database.ymlを読み出せませんでした' if config[params['ENV']].nil?
raise ArgumentError, 'csvファイルが存在しません'          unless File.exists?(params['csv'])

ActiveRecord::Base.establish_connection(config[params['ENV']])
class User < ActiveRecord::Base
end

column = %w(user_external_id  name birthday)
CSV.foreach(params['csv']) do |row|
  # 一行を全部hashに入れる
  row_hash = {}
  row.each_with_index do |r,idx|
    row_hash[column[idx]] = r
  end

  user = User.find_by_external_id(row_hash['user_external_id'])
  if !user.nil?
    user.update_attribute(:name => row_hash['name'])
  end
end

実行はターミナルで

1
2
3
ruby 上記コードのファイル --ENV production
もしくは
bundle exec ruby 上記コードのファイル --ENV production

とかとか

スクリプトのオプションは
–ENVはdatabae.ymlの読み込みたい環境{development|production}
–csv で読み込むファイルパス
–RAILS _ROOT でRailsのapp rootを指定。

さらさらっと書いて本番のrails rootで動かしてパッチを実際に当てましたが。
仕事にかかわる記述は消したり直したり、ロクにテストしていないので動かなかったらごめんなさい。


半角カナが入力されているファイルを抽出

お客様から、半角カナを全角カナにしておくれと依頼がきていたので、railsのrootから半角カナを含むファイルを抜き出したくてスクリプト書きました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/usr/bin/env ruby

require 'find'

except_ext = %w(.log .yml .jpg .JPG .jpeg .png .pid .ttf .woff .md .json .ico .eot .gif)                                                    # 除外するファイル拡張子を設定
except_pattern = %w(.git test .DS_Store migrate hankaku_kana_checker RackMultipart sprockets letter_opener underscore cache)                # 除外するパスに含まれる文字列を指定

# チェックする半角カナの配列
han_kana =  %w{ア イ ウ エ オ カ キ ク ケ コ サ シ ス セ ソ タ チ ツ テ ト ナ ニ ヌ ネ ノ ハ ヒ フ ヘ ホ マ ミ ム メ モ ヤ ユ ヨ ラ リ ル レ ロ ワ ヲ ン ァ ィ ゥ ェ ォ ャ ュ ョ ッ ゙ ゚ 、 。 ー 「 」}

Find.find(File.expand_path('./')) do |path|
  next if File.directory?(path)
  next if except_ext.include?(File.extname(path)) # 調査しない拡張子
  next if path.match(Regexp.new(except_pattern.join("|")))

  begin
    File.readlines(path).each.with_index(1) do |line, idx|
      @idx, @line = idx, line
      # CP932のファイルが混在してたのでダメならCP932で変換
      include_han_kana = begin
                           line.match(Regexp.new(han_kana.join("|")))
                         rescue
                           line.encode("UTF-8", "CP932").match(Regexp.new(han_kana.join("|")))
                         end

      if include_han_kana
        p [idx, path, line].join(": ")
      end
    end
  rescue => ex
    p "####################################################################################################"
    p [@idx, @line].join(": ")
    p [ path, ex.message ].join(":")
    p ex.backtrace.first
    p "####################################################################################################"
  end
end

再帰的にディレクトリをくだって、探します。
含めたくないファイル名やディレクトリ名。拡張子を指定できます。

良かったら使ってみてください。


Terminalでsshするときに、接続先に応じて背景色を変える方法

朝これを見た。

iTermでsshするときに、接続先に応じて背景色を変える方法
http://qiita.com/k_kinukawa/items/3e5665325a4954e33019

いいなと思った。

でも普段僕はMacの標準のTerminalを使っている。
Terminalで同じこと出きないかなとぐぐったらすぐあった。

https://github.com/dlobraico/dotfiles/blob/master/bin/ssh-host-color

でも僕は透過率が75%にしていて透過率を設定したいのだけど。
osascriptで透過率の設定がよくわからない。

というか普段ターミナルの色とかはProの設定を使っているのでProの使いたいなーって思ってググってprofileを切り替えられるようにした。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#!/bin/bash
#
# ssh into a machine and automatically set the background
# color of Mac OS X Terminal depending on the hostname.
#
# Installation:
# 1. Save this script to /some/bin/ssh-host-color
# 2. chmod 755 /some/bin/ssh-host-color
# 3. alias ssh=/some/bin/ssh-host-color
# 4. Configure your host colors below.

set_term_bgcolor() {
   local R=$1
   local G=$2
   local B=$3
   /usr/bin/osascript <<EOF
tell application "Terminal"
   tell window 0
      set the background color to {$(($R*65535/255)), $(($G*65535/255)), $(($B*65535/255)), 32767}
   end tell
end tell
EOF
}

set_term_profile() {
   local profile=$1
   /usr/bin/osascript -e "tell application   "Terminal  " to  set current settings of first window to settings set   "$profile  ""
}

# Host-specific background colors.
if [[ "$@" =~ production1.com ]]; then
   set_term_profile "HomeBrew"
elif [[ "$@" =~ production2.com ]]; then
   set_term_bgcolor 0 40 0
fi

ssh $@

# Default background color.
set_term_profile "Pro"

set term profileでプロファイルの名前を渡せばそれに切り替わる。
set bg colorも残してる。



jsでformの取り消す・やり直す

javascript力が弱くて、クラス使って何か書きたくて、しかも coffeescriptで書きたくて、
CTRL + Z というブラウザの標準の機能があるのに、jsで戻る、やり直しを行うことができるプラグインを作りました。
正直使い道がよくわかりません。どのあたりをターゲットにしているのかもちょっとわかりません。

こんな感じでエレメントを指定してformを対象にして

1
form = new FormObserver('form');
1
2
3
4
// 一つ前の操作に戻す
form.undo();
// やり直し
form.redo();

って感じで、操作できます。

IE10とchromeでは動きました。
よくテストはしてません。
バグがあったらすいませんすいません。

使って見たい方はこちらからどうぞ
https://github.com/YoshitsuguFujii/form-undo.js


変数の初期化

clearなんてあったんや。
http://ref.xaio.jp/ruby/classes/array/clear

今まで

1
2
array = ["hoge", "fuga"]
array = []

ってやってたのが、

1
2
array = ["hoge", "fuga"]
array.clear # => []

って書ける。より直感的ですね。

ちなみに文字列もHashもあるみたいです。

1
2
3
4
5
hash = {hoge: "fuga"}
hash.clear # {}

str = "fugafufa"
str.clar # => ""

へー。