ひよっこエンジニアの雑多な日記

なんとかWeb系のエンジニアをやっています。

【Nginx】apple-touch-iconに攻め込まれる場合の対処

2ヶ月ぶりくらいの更新です…
毎度お世話になっております。きむらです…

最近色々とやばいことが重なりすぎて人生が楽しくなってきています。(白目)

さて今日はちょっとした記事ではありますがタイトルの通りの設定を備忘録代わりに書いときます!

状況

現在Nginx+Unicornで運用しているRailsアプリケーションがapple-touch-iconに攻められまくり、apple-touch-iconをサーバに配置していないのでRoutingエラーを弾き出しまくっていました…
そしてイケてないエラーハンドリングをしてしまっているのでアクセスされるたびにアラートメールが飛んでくる…
一時間に10通は送信されてくるので煩わしさが半端じゃない!!(エラーハンドリング改善しろって話なんですけどね…はい…)
Nginxでそのアクセスをさばいていなかったので、Unicornまでアクセスが到着してしまっているという状況でした…

解決策

一番はapple-touch-iconを設置してしまうことなのですが、用意しているわけではなかったのでNginxパイセンにさばいてもらうことにしました

root /アプリまでのパス/current/public;

location / {
     ルートパスの設定
}

location ~ ^/(apple-touch-icon*) {
     キャッシュの設定とか
}

ひとまずapple-touch-iconなんとかへのアクセスがあったら/アプリまでのパス/current/public配下を見せるように設定を記述しました。
これでapple-touch-iconなんとかを配置していなくてもNginxパイセンが404をはじき返してくれて、Unicornさんが怒りのアラートを出すことがなくなりました!一安心!

とりあえず最近手掛けてるアプリの作りやばいし、色々やばいし、色々頑張んなきゃいけないしでつらたん
今、誰かに優しくされたら惚れてまいそう(真剣)

mysqlでメールアドレスにマスクをかけるよ

今回は2週間ぶりくらいの更新!
ちょっとずつ間隔を短くしたい!

今回は件名の通りmysqlでメールアドレスにマスクをかけます。
hogehoge@example.com -> xxxxxxx-1@example.com
上みたいな感じにします!

シチュエーションとしては

  • 本番データをステージングに突っ込みたいけど個人情報やし、うかつに突っ込めない…
  • そんなときはメールアドレスにマスクをかけちゃお! みたいな感じです

兎にも角にも手順

1. 本番環境からdumpとる
2. ローカルにdumpを突っ込む(DBは作成してからNE)
3. マスクかけるupdate文を流す

update 'テーブル名' set 'emailのカラム' = replace('emailのカラム',left('emailのカラム',instr('emailのカラム','@')-1),concat('xxxxxxx_',id));

4. ローカルからdumpとる
5. scpでステージングに送る
6. ステージングでDBにdump突っ込む
7. 優勝

きょうのはんせいてん

インフラ触るときは1字1句の誤字脱字のチェック、
なにか質問するときはまず自分で確認できるところはないか考えてから
ちゃんと足りないことがないか確認してからアクションする

備考

postgresqlの場合はこうする

update 'テーブル名' set 'emailのカラム' = replace('emailのカラム',substring('emailのカラム', 1, strpos('emailのカラム','@')-1),concat('xxxxxxx_',id));

bootstrap datepickerで土日の色を変えるよ!

気がついたら、また前回更新から一ヶ月の時が過ぎてしまっていました…
この一ヶ月間は転職したり引っ越ししたりとかなりバタバターっとしていて割と人生的に変換期に入ってきている感があります…!

今回はbootstrap datepickerについて書いていきたいと思いますー!
ちょっと開発をしていてカレンダーから日付入力したいなーと考えた時にお手軽に実装できると噂のbootstrap datepickerを導入しました。
それで土日だけ色を違う色にしたいなーと思ったりして色々調べたものの日本語記事であまり情報がなかったので今回の題材にしようかなーと思いました。

(今回もRails開発の中での導入なのでGemを使って導入していたりしますがご愛嬌ということで…)

bootstrap datepickerを導入するよ!

1. Gemfileに追記

gem 'bootstrap-datepicker-rails'

2. bundle install
3. application.jsに追記

//= require bootstrap-datepicker/core
//= require bootstrap-datepicker/locales/bootstrap-datepicker.ja.js

とりあえず言語は日本語だけで良いのこんな感じ

4. application.cssに追記

 *= require_self
 *= require bootstrap-datepicker3
 *= require_tree .

これで一通り準備は完了!

bootstrap datepicker使ってみるよ!

javascript
$(document).ready(function(){
  $('.datepicker').datepicker();
});
HTML
<div class="input-group">
    <!-- erbの書き方なので注意 -->
    <%= f.text_field :input_date, class: "form-control datepicker" %>
</div>

とりあえずちょいちょいっとこんな感じで書くと下のような感じになります!
f:id:kimuraysp:20160716235227p:plain

とはいえかなり質素感が半端ないですね…
せめて土日だけでもわかりやすくなってほしい…

土日に色をつけるよ!

ということで土日に色をつけましょう!
まずはjavascriptを改良

javascript
$(document).ready(function(){
  $('.datepicker').datepicker({
    beforeShowDay: function(date) {
      var myDate = new Object();
      if (date.getDay() == 0) {
        myDate.enabled = true;
        myDate.classes = 'class-sunday';
        myDate.tooltip  = '日曜日';
      } else if (date.getDay() == 6) {
        myDate.enabled = true;
        myDate.classes = 'class-saturday';
        myDate.tooltip  = '土曜日';
      } else {
        myDate.enabled = true;
        myDate.classes = 'class-weekday';
        myDate.tooltip  = '平日';
      }
      return myDate;
    }
  });
});

beforeShowDayを設定することで日付表示の前に処理を行ってくれる。
ここの感じだとobjectにenabled, classes, tooltipを設定できるとのこと。
今回大事なのはclassesです!
これを使うことで色を変えたい曜日を判別します。

まずカレンダーに表示される日にちは1日単位でtd要素と成っているということを念頭に置いておいてください。
一日ごとにbeforeShowDayをみて処理を行います。
そこでif (date.getDay() == 0)みたいな感じで日にちと謎の数字を判定しています! この謎の数字は日〜土を表していて0〜6で表現されます。 なので0だったら日曜日の処理、6だったら土曜日の処理、それ以外は平日の処理をやってね!ということになります。

で次に設定する内容についてです。
enabletooltipは本質じゃないので割愛で…
大事なのはclassesこれに設定した値は一日単位で生成されるtd要素のclassとして追加されます。

そしてclassが追記されることでスタイルを当てることができるようになります!

.class-sunday {
  color: red !important;
}
.class-saturday {
  color: blue !important;
}

これをcssで記入してやることで

f:id:kimuraysp:20160717001759p:plain

こんな感じで土日に色がつきちょっとおしゃれな感じになりました!

おまけ

入力フォームをちょっとおしゃれにする

<div class="input-group">
  <%= f.text_field :input_date, id: "date-area", class: "form-control datepicker" %>
  <label for="date-area" class="input-group-btn">
    <span class="btn btn-success"><i class="fa fa-calendar"></i></span>
  </label>
</div>

f:id:kimuraysp:20160717002233p:plain

bootstrapと合わせることでちょっとおしゃれなdatepickerの入力フォームができてしまいます!
bootstrap datepickerというだけありbootstrapとの親和性は高いですね!

さて今回はbootstrap datepickerについて書きました。
探してた時は藁にもすがる思いでしたがわかってみると意外となんてことないコードでした。
こういう微妙にハメられる系を見つけ次第どんどん記事にしていこうと思います(また次は一ヶ月後かなあ…笑)

【Rails】Ajaxでセレクトボックスの内容を動的に変更する

こんばんは!1週に一回記事更新しますわ〜とか言っておきながら1ヶ月ぶりの更新です…笑

今回の内容は2つのセレクトボックスがあった時に片方のセレクトボックスが変更されたら、もう片方のセレクトボックスで選択できる内容が動的に変更されると言った内容です!
概要だけだと何言ってるかわけわからないと思うので例を挙げると、県と市区町村が選択できるセレクトボックスがそれぞれ存在する時に、県を選択したら市区町村のセレクトボックスの方が選択された県に存在する市区町村が選択肢になるようなイメージです。

どう作ればいいかわからない状態から作ったのでかなり時間がかかったので備忘録がてら書いときます

想定

とりあえずテーブル構造はこんな感じ

f:id:kimuraysp:20160616234834p:plain

prefecturesとcitesとマスタテーブルとしていて存在していて、そんでprofilesに住んでいる県と市区町村が登録されるみたいな想定

ビュー

new.html.erb

<%= form_for(@profile) do |f| %>
  <% if @profile.errors.any? %>
    <div id="error_explanation">
      <ul>
      <% @profile.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="prefecture-area">
    <%= label :prefecture_id %><br>
    <%= collection_select :profile, :prefecture_id, Prefecture.all, :id, :name %>
  </div>
  
  <div class="city-area">
    <%= render partial: 'select_city', locals: {prefecture_id: Prefecture.first.id} %>
  </div>
<% end %>

_select_city.html.erb

<%= label :profile, :city_id %><br>
<%= collection_select :profile, :city_id, Prefecture.where(prefecture_id: prefecture_id), :id, :city_name %>

動的にセレクトボックスを入れ替えるcity_idの方はselect_cityという名前でパーシャル化。
パーシャル化することでAjaxで返ってくる結果をレンダリングしやすくしとく。

コントローラ

class ProfilesController < ApplicationController
  def new
    @profile = Profile.new
  end

  # Ajax処理を行う処理
  def get_cities
    render partial: 'select_city', locals: {prefecture_id: params[:prefecture_id]}
  end
end

セレクトボックスを動的に変える処理をget_citiesというアクションで受け取る。
Ajaxでこのアクションを呼ぶ。
ルーティングは以下の感じで

Rails.application.routes.draw do
  resources :profiles, only: :new do
    collection do
      get 'get_cities' # /profiles/get_cities
    end
  end
end

モデル

今回の記事の本質からは外れるので割愛します。
だいたいテーブル構造で想像してください。

Coffee Script

セレクトボックスを動的に変えるのはAjaxを使って実現するためcoffeeやjavascriptが肝になる。
ここがいまいちわかっていなかったので色々詰まっていた…

$(document).on 'change', '#profile_prefecture_id', ->
  $.ajax(
    type: 'GET'
    url: '/profiles/get_cities'
    data: {
      prefecture_id: $(this).val()
    }
  ).done (data) ->
    $('.city-area').html(data)

$(document).on 'change', '#profile_prefecture_id'
この処理でprefecture_idのセレクトボックスが変更されたことを検知する。
profile_prefecture_idはcorrection_selectで自動生成されるid。correction_selectというよりForm系のヘルパーで生成される。

$.ajax(
    type: 'GET'
    url: '/profiles/get_cities'
    data: {
      prefecture_id: $(this).val()
    }

ここでAjaxの通信を開始している。typeにメソッド、urlに呼び出すアクションのパス、dataにコントローラに渡す値を設定する。
今回のdataはセレクトボックスで選択された値をparamsprefecture_idとして乗せる。

done(data)でアクションの結果を受け取る。今回のアクションはprofilesコントローラのget_citiesアクションでget_citiesの中身はrender partial: 'select_city', locals: {prefecture_id: prefecture_id}なので_select_city.html.erbレンダリングした結果を受け取る。
アクションの処理結果はdataに格納されている。

ここのdata$.ajaxでコントローラに渡したdataとは別もんな気がするので注意。

$('.city-area').html(data)レンダリングされたHTMLソースを<div class="city-area">内に差し込むことでセレクトボックスを入れ替える。

ここまでやることでセレクトボックスの入れ替えが実現できました!

いざ記事にしてみると大して難しいことはやっていないのだけど、初めて実装する機能などはやはり難易度が高いように感じてしまう…。
こうやって色々試して、ブログなんかで知識を蓄積して慣れていくしかないですかね…。

うわぁ、がんばろう

【Rails】enumをI18n対応させるenum_helpが便利すぎた

Railsでの開発を通して色々なgemを教えてもらったりして常に目から鱗状態という最近の事情です。

その中でenum_helpというenumI18n化するgemが個人的に簡単かつ便利だなーと思ったのでご紹介です!

まずenumとは何者か

enum0を男性, 1を女性のように数字を何かしらの値と紐付けているようなデータの管理をしている場合に非常に有効なものです。

例えばUserモデルで性別をgenderで管理している場合に男性を0, 女性を1としていると想定

class User < ActiveRecord::Base
  enum gender: { male: 0, female: 1 }
end

このように書くと

# genderに0を設定している場合
user.gender
=> "male"

# genderに1を設定している場合
user.gender
=> "female"

こんな感じでgenderを数字ではなく、文字列で扱うことができるようになって直感的になるし、色々と便利ヘルパーが付加されるので、こんな感じのデータ構造を取っている際は積極的に設定するべき!(ただRails4.1から導入された機能っぽい)

enumI18n対応させたい!

user.genderと書いて"male"や"female"とでるのは素敵だけど、日本語で"男性", "女性"と表示させたいと日本人の僕的には思うわけですよ…
ただ素の状態のenumI18n化するのは若干面倒くさそう…

そこででてくるのがenum_helpという便利gemです!! 使い方も簡単でenum_helpを導入してlocalesを設定するだけ!

enum_helpを導入しよう!

1. まずは例のごとくGemfileに導入するgemを追記する

gem 'enum_help'

2. bundle install

3. localファイルに追記

config/locales/ja.yml

ja:
  enums:
    user:
      gender:
        male: 男性
        female: 女性

4. あとは呼び出すだけ!

呼び出すときはenumを設定している属性を呼び出す際に◯◯_i18nとするだけ!

# genderに0を設定している場合
user.gender_i18n
=> "男性"

# genderに1を設定している場合
user.gender_i18n
=> "女性"

これでenumI18n化は完了なんです!
本当にgem入れて、locales設定するだけでenumI18n化ができちゃうので簡単ですね!

おまけ

enum_helpを設定すると便利ヘルパーが付与される

# 設定しているenumをハッシュで展開
user.genders_i18n.invert
=> {"男性"=>"male", "女性"=>"female"}

ビューでselect_boxを設定する際などに重宝します!

もっといろんなgemとか覚えて、効率的にRails開発をできるように精進したい今日この頃。

RSpecの基本的な部分を勉強してみた

ブログだいぶサボってました…。
いよいよまずいと思ったので久々に更新です。

今回はRSpecについてだらっと書きます。
Ruby on RailsでWebアプリを作る営みをしているのですが、テストをかなりおざなりにしていた+テストの書き方がイマイチわからない状態というブログ更新を滞ったよりもまずい状況だったので勉強しました。

ざっくり学んだことをもはや個人的なメモとしてだらだら書いていきます。
がっつり理解できているわけではないので内容的に曖昧なところもあるので悪しからずです…。

RSpecとはなんぞや?

Rubyのテストフレームワークの一つで、テストを書くのに特化したDSLとかいうやつみたいです。

RSpecを使うために

  • rspec --initで.rspecとspecディレクトリが作成される
  • テストを記述したファイルはspecフォルダに格納
    • xxxx_spec.rbみたいなファイル名にする
  • テスト実行はrspecコマンドを使用する
    • -fdオプションをつけるとテスト毎の成否が見れるようになる

RSpecの基本的な書き方

RSpec.describe "テスト名(クラス名とか)" do
  before do
  end
  
  it "テストケース(メソッドとか)" do
  end

  it "テストケース" 
end

beforeメソッド

  • テスト実施前の初期処理を書く(インスタンス生成とか)
  • beforeで生成した変数は変数の前に@をつけてインスタンス変数のように宣言する必要あり
  • beforeの引数には:exampleと:contextがある
    • :exampleは各exampleの前に実行される(引数省略で:exampleとなる)
    • :contextはdescribeの中の最初の一回目に実行される

example

  • it 〜 endのこと(1テストケースを指す?)
  • itはexample / specifyと書くことも可能
    • テストケースのところに書く文と文脈があうようなものを適宜選択する
  • ブロックを記載しないとpending(棚上げ)となる

describe / context

  • テスト対象を指定する(exampleのグループ化ができる)
  • describeもdescribeの中で入れ子にできる
  • トップレベルのdescribeはクラス名を書く
  • describeと同様に使うことができる
    • describeが物、contextが状況という使い分けをする

matcher

期待する振る舞いを指定する記号を指す

matcher一覧

  • eq(x):xと等しいか
  • not_eq(x):xと等しくないか
  • be [true/false]:trueかfalseか
  • be < x:xより小さいか
  • be_between(x, y).inclusive:数値がxとyの範囲内か(xとyも範囲に含む)
  • respond_to(:{メソッド名}):そのメソッドが存在しているか
  • Rubyの特徴を生かした書き方
    • 例として結果がintegerかどうか調べるテスト を書く expect(obj.add(2,3).integer?).to be true
      上記の書き方を
      expect(obj.add(2,3)).to be_integer
      と書くことができる

subject

RSpec.describe Sample do
  it {
    sample = Sample.new
    expect(sample.add(2, 3)).to eq(5)
  }
end

これを

RSpec.describe Sample do
  it {
    expect(subject.add(2, 3)).to eq(5)
  }
end

にできる。
しかし、このままだとテストケースが長くなった時にsubjectってなんだっけとなってしまうので以下のように書く。

RSpec.describe Sample do
  subject(:sample) { Sample.new }
  it {
    expect(sample.add(2, 3)).to eq(5)
  }
end

subjectにシンボルを渡して{}内でnewしてやるとsampleインスタンスとして使えるようになる。
beforeを使えば良いじゃないかという話もあるがbeforeだとexample内でインスタンス変数を使う必要が出るためsubjectの方がスッキリする。(好みの問題的な側面もあるらしいが…)

method stub

メソッドをまだ実装していないけどテストに使用したいよーという場合に使う。
ex)Userモデルから名前を取得するnameメソッドを使いたいけどまだできてないよーっていう場合

RSpec.describe Sample do
  it {
    #test doubleの呼び出し
    #doubleの引数はなくても良いが失敗した時などに便利なので書いておく
    user = double('user') 
    #nameメソッドが呼び出されたら強制的にtanakaを返すようにする
    allow(user).to receive(:name).and_return('tanaka')
  
    sample = Sample.new
    expect(sample.add(5, user.name)).to eq('5 by tanaka')
  }
end

message expectation

呼ばれなかったらテストが失敗する。
ある処理の前に確実にある処理が走っていることを保証したい場合に使用する。
ex)ログの処理を書いていなけどログを書く処理が各区実に呼ばれたかテストしたいよーっていう場合

RSpec.describe Sample do
  it {
    #ロガーのtest doubleを作成する
    logger = double('logger')
    #loggerのlogメソッドが呼ばれていることを確認する
    expect(logger).to receive(:log)
    #sampleクラスでloggerインスタンスを使用する想定
    sample = Sample.new(logger)
    expect(sample.add(5, user.name)).to eq('5 by tanaka')
  }
end

あー、久々に記事書きましたー。
文章書くのは訓練しないとどんどん書けなくなりますね…
これからは週に最低1記事を目標にブログ頑張ります!

ドットインストールで快適に学習するために『Dotinstall Pane』を使ってみた

プログラミング初心者の強い味方といえば『ドットインストール - 3分動画でマスターする初心者向けプログラミング学習サイト』がありますね。

動画を見ながらプログラミングを学習するサイトで、学べる内容が豊富でどれから手をつければいいのかしら?となるうれしい悲鳴が上げられる感じのサービスです。
学習の方法としては動画でやっていることを写経して、実行してを繰り返す感じ。
ただ写経して、実行のためにブラウザを立ち上げて〜という動作を繰り返すのは割とだるい印象。

ただ最近ドットインストールのメルマガで『dotinstall-pane』なるものを知り、取り入れてみたところ結構便利だったので紹介していこうかと思った次第。

Atomをインストールする

まず『dotinstall-pane』はテキストエディタAtom』のプラグインなので『Atom』を導入する。

自分はMacを使用しているのでMacのインストール方法を記載する。

  1. 公式サイトにアクセスする。http://atom.io/
  2. 公式サイトにある『Download For Mac』ボタンをクリックする。
  3. ダウンロードしたファイルを解凍する。
  4. 解凍したファイルをアプリケーションフォルダに配置する。

これでインストールは完了!

windowsの場合は以下のサイトが参考になります。
Windows - テキストエディタ「Atom」のインストール - 開発メモ - Webkaru

また『Atom』はデフォルト英語なので、日本語化したい場合は以下を参考にすると良さげ。
Atom の日本語化パッケージ "Japanese Menu" を作りました - syonx

『Dotinstall Pane』を導入する

Atom』のインストールが完了したら本題の『dotinstall-pane』を導入する。
※日本語化を行っているので操作項目がデフォルトの状態とは若干異なります。

まずAtomを起動し、ツールバーの『Atom > 環境設定』を選択する。
f:id:kimuraysp:20160214123051p:plain

環境設定画面に遷移したら、サイドバーから『インストール』をクリックする
f:id:kimuraysp:20160214123351p:plain

その後パッケージの検索バーに『dotinstall』と入力しエンターを押すことで検索をかける。
検索をかけると『dotinstall-pane』が出てくるので『install』ボタンをクリックしてインストールする。

これで『Dotinstall Pane』の導入完了です!

『Dotinstall Pane』を使用する

さて導入が終わったらいよいよ使ってみる!

使用方法はすごく簡単で

Macなら『Option + Shift + D』
Windowsなら『Alt + Shift + D』

上記のキーをエディタ画面で押すだけ!!
f:id:kimuraysp:20160214124457p:plain

するとエディタの横にドットインストールの画面が出てきちゃいます!
これで動画みながら学習が効率よくできるようになります!

さらに便利にするために

公式ブログ『http://blog.dotinstall.com/post/139045656660/dotinstallpane』にもありますが、『atom-html-preview』を導入すると学習効率がかなり上がります。

atom-html-preview』ってなんぞやとなりますが、これはエディタ上でショートカットキーを押すことでブラウザでの見え方を簡単に確認できるプラグインです。

導入方法は『Dotinstall Pane』と同様にツールバーの『Atom > 環境設定』と進み、サイドバーで『インストール』を選択する。
その後検索バーに『atom-html-preview』と検索して、『install』ボタンをクリックしてインストールします。
[f:id:kimuraysp:20160214125708p:plain

使用方法はエディタでHTMLを記述して、
f:id:kimuraysp:20160214130114p:plain
(このソースはjQuery入門第6回授業のものになります)

エディタにフォーカスを当てつつ、ショートカットキー『Ctrl-Shift-H』を入力するだけ!
f:id:kimuraysp:20160214130414p:plain
するとピョロっと右側にブラウザでの見え方が表示されます!

この二つのプラグインを導入することで学習効率がすごい上がった気がします!
特にHTML,CSS,javascript系の学習効率が跳ね上がります。

プログラミングに興味がある人はこれを導入して学習を始めるのもありっぽいかも。