元祖若手のプログラミング奮闘記

元祖若手の奮闘記。主に注意されたことをメモがわりに使用するよ!

VargrantのguestOSのversionが合ってなくてエラーになってたのを直した

お世話になっているvargrant
なんかごにょごにょしたらエラーが出てしまった

$ vagrant up
(前略)
[default] GuestAdditions versions on your host (5.1.28) and guest (5.0.6) do not match.

(中略)

because the filesystem "vboxsf" is not available. This filesystem is
made available via the VirtualBox Guest Additions and kernel module.
Please verify that these guest additions are properly installed in the
guest. This is not a bug in Vagrant and is usually caused by a faulty
Vagrant box. For context, the command attempted was:

mount -t vboxsf -o uid=1000,gid=1000 vagrant /vagrant

The error output from the command was:

mount: unknown filesystem type 'vboxsf'

[default] GuestAdditions versions on your host (5.1.28) and guest (5.0.6) do not match.


よはguestOSのversionを合わせればいいんだなって思い

vargrant ssh

でログイン

$ curl -0 http://download.virtualbox.org/virtualbox/5.1.28/VBoxGuestAdditions_5.1.28.iso > /tmp/vboxguest.iso
$ sudo mount -o loop /tmp/vboxguest.iso /mnt
$ yes yes | sudo /mnt/VBoxLinuxAdditions.run
$ exit

ほんで読み込み直しておしまい

myuser: centos7$ vagrant reload
==> default: Attempting graceful shutdown of VM...
==> default: Checking if box 'bento/centos-7.1' is up to date...
==> default: Clearing any previously set forwarded ports...
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
    default: Adapter 2: hostonly
==> default: Forwarding ports...
    default: 3000 (guest) => 3000 (host) (adapter 1)
    default: 22 (guest) => 2222 (host) (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
==> default: Machine booted and ready!
[default] GuestAdditions 5.1.28 running --- OK.

(後略)

.bashrcで作業効率アップ

長いコマンドをパイプ繋いで頑張っていた
今日この頃

.bashrcで設定して作業効率向上させたお話

こんなコードをいちいち打つのはめんどくさい

$ history | grep mysql


まずbashrcを作成

$ vi ~/.bashrc

i
を押して編集モードにする
そして下記エイリアスを作成

alias hgrep='histroy | grep'

escキーを押してコマンドモードに戻して

:wq
を押して保存して終了

$ source ~/.bashrc

これで先ほど作った hgrep が
有効になります。
もし失敗したらターミナル再起動

$ hgrep mysql

またこんなコマンドはさらにめんどい

$ find app/controller -name "*.rb" | xargs grep -r "debug"

そういったときはfunctionを使う
またまた.bashrcを編集する

function fgrep() {
  command find $1 -name "*.$2" | xargs grep -r "$3"
}

また.bashrcを読み込み直して
無事に動きました

$ fgrep app/controllers rb debug

おすすめエイリアス
あればぜひ教えていただきたい。。

Rails 参考になる書き方書いてあった

ちょっとした細かいところまで書いてある!!
これは使える!


github.com

RailsのModelを複雑にした時

SQLのこんな動きをしたい
UPDATEする時JOINしてGROUPBYしてって時

update
  items
inner join (
  select
    orders.item_id,
    count(*) count
  from
    orders
  group by
    item_id
  ) myorders
set
  items.orders_count = myorders.count
 where
  items.id = myorders.item_id


Arelなら綺麗にかけるけども
現場でArelを使ってかいてなかった。。

って時に考えた結果こうなった
ベタ書きってどうよ。。

order = Order.select("#{Order.tn}.item_id, COUNT(*) count").group(:item_id)
Item.joins("INNER JOIN (#{order.to_sql}) myorders")
  .where("#{Item.tn}.id = myorders.item_id")
  .update_all("#{Item.tn}.orders_count = myorders.count")

PHPの正規表現でWARNINGがでまくったのでとめた。

こんなコードを書いていたら
WARNINGがでまくったので

<?php
    public function validateWords($word_list = array()){
        $pattern = implode('', array(
            "\x{3041}-\x{3094}", //ひらがな
            "\x{30A1}-\x{30F3}", //カタカナ
            "\x{4E00}-\x{9FFF}", //漢字
            "\x{F900}-\x{FAFF}", //漢字
            "\x{FF01}-\x{FF5A}", //全角記号、全角英数字
            "a-zA-z0-9Α-Ωα-ω¢£"
        ));

        $result = array();
        foreach ($word_list as $word){
            if (preg_match('/[^'. $pattern .']/', $word)){
                $result[] = $word;
            }
        }
    }
    return $result;
?>

そしてこんな感じでWARNINGがでた

Warning: pregmatch() [function.preg-match]: Compilation failed: invalid range in character class at offset 13

まぁ範囲の指定がUnicodeとa-zとかごちゃってるからな
ってことで

全部統一してみる
だがしかしWARNINGは止まらない

そして気づく。

「そういえばこれEUC-JPやんけ。。」

ってことで修正

<?php
    public function validateWords($word_list = array()){
        $pattern = implode('', array(
            "\x{0030}-\x{0039}", //半角数
            "\x{0041}-\x{005A}", //半角英小
            "\x{0061}-\x{007A}", //半角英大
            "\x{3041}-\x{3094}", //ひらがな
            "\x{30A1}-\x{30F3}", //カタカナ
            "\x{4E00}-\x{9FFF}", //漢字
            "\x{F900}-\x{FAFF}", //漢字
            "\x{FF01}-\x{FF5A}", //全角記号、全角英数字
            "\x{FFE0}\x{FFE1}" //セント、ポンド
        ));

        $result = array();
        foreach ($word_list as $word){
            $str = mb_convert_encoding($str, "UTF-8", "EUC-JP"); // UTF-8へ変換

            if (preg_match('/[^'. $pattern .']/u', $str)){ //u修飾子をつけ忘れないように
                $result[] = $word;
            }
        }
        return $result;
    }
    
?>

WARNING止まった!!!!

だが待つんだ
喜ぶのはまだ遅かった
全角のマイナスとセント、ポンドがなぜか
NGワードでひっかかる

ってことで
UTF-8に変換したところでvar_dump
なんと半角に変換されていた。。。。

-¢£ => -¢£
ってことなので
範囲を追加。

下のやつでおしまい。

<?php
    public function validateWords($word_list = array()){
        $pattern = implode('', array(
            "\x{0030}-\x{0039}", //半角数
            "\x{0041}-\x{005A}", //半角英小
            "\x{0061}-\x{007A}", //半角英大
            "\x{3041}-\x{3094}", //ひらがな
            "\x{30A1}-\x{30F3}", //カタカナ
            "\x{4E00}-\x{9FFF}", //漢字
            "\x{F900}-\x{FAFF}", //漢字
            "\x{FF01}-\x{FF5A}", //全角記号、全角英数字
            "\x{FFE0}\x{FFE1}" //セント、ポンド
            "\x{2D}\x{A2}\x{A3}"
        ));

        $result = array();
        foreach ($word_list as $word){
            $str = mb_convert_encoding($str, "UTF-8", "EUC-JP"); // UTF-8へ変換

            if (preg_match('/[^'. $pattern .']/u', $str)){ //u修飾子をつけ忘れないように
                $result[] = $word;
            }
        }
        return $result;
    }
    
?>

PHPの配列(array_diff)を甘くみていたらはまった

これは特殊なケースかなと思ったけど一応メモ。

PHPの配列を深く知らなかったがために
結構はまった。。

追加した処理が二つの配列を比較して
新たにデータを追加したり、削除するような機能を作りたいとする。

<?php
$array1 = array("green", "red", "blue", "red");
$array2 = array("green", "yellow", "red");
$result = array_diff($array1, $array2);

print_r($result);
?>

こちらの$resut変数をそのまま引数として渡すとこうなる

Array
(
    [1] => blue
)

ここの添え字が [1] になっているのが
かると思うが

添え字もしっかり [0] にして渡さないと
エラーになってしまうことがつい最近わかった
ってことで初期化

<?php
$array1 = array("green", "red", "blue", "red");
$array2 = array("green", "yellow", "red");
$result = array_diff($array1, $array2);

print_r(array_merge($result));
?>
Array
(
    [0] => blue
)

これでオッケー
もう値はあってるのになんで。。。
みたいなことはなくなるかと

Raisでコードの書き方で指摘されたこと

Railsで指摘されたことをまとめる

・アロー演算子を使わない

  # 古いコードを見ながら書くとついついやるやつ
  validates :name, :presence => true
  # こっちの書き方で
  validates :email, presence: true

・evalを使わない
セキュリティ上よくないらしいけど
深くまで知らない
あと例が悪くて申し訳ない。。

  _params = set_params
  search_types = []
  if _params[:name].present?
    name_ids = User.get_ids_by_name(_params[:name])
    search_types << "name_ids"
  end

  if _params[:email].present?
    email_ids = User.get_ids_by_email(_params[:email])
    search_types << "email_ids"
  end

  # &にすることで二つの配列で同じ値のみ代入される
  # merge_ids = name_ids & email_ids
  merge_ids = eval(search_types.join("&"))

・長い1行を改行するときのインデント
 メモ残すまでって感じではないけど一応。。

  # こうするとselfを変えた際に
  # いちいちインデントをそろえなくちゃいけない
  self.where(name: my_name)
      .where(email: my_email)
      .first

  # これで
  self.where(name: my_name)
    .where(email: my_email)
    .first

まだまだ言われてるけど
まずはこれくらいで