hotoolong's blog

プログラムのことやエンジニアリングに関することを記事にしています。

dotinstallのプレミアム会員の料金改定

いつもお世話になっているドットインストールのプレミアム会員の価格が改定されるそうです。

月額880円から980円になるそうで、4月からの適応だそうですので迷っていたかたは今かもです。

『ドットインストール』公式ブログ — プレミアムサービスの価格を改定いたします

Rails4.2でlike句のサニタイズをする

2016年はじまってもう2月になってしまいました。 遅ればせながら、あけましておめでとうございます。

昨年から相当ハードなスケジュールでなかなかブログが書けてないですが、 今年はもう少し書く時間を確保したいところ。 頑張ります。。

今日のお題は SQLでLike句を使う場合に RailsActiveRecordを使ってwhere句

Hogehoge.where('name LIKE ?', "%#{args[:name]}%") 

の様な書き方をするケース もしくはscopeでArelに設定して

scope :by_name, ->(name) {
  where(arel_table[:name].matches("%#{name}%"))
}

の様な書き方もよく見かけますが、 like句に対してサニタイズするのを忘れてしまうこともあります。

Rails4.2からサニタイズするメソッドが利用できるようになってます。 http://apidock.com/rails/v4.2.1/ActiveRecord/Sanitization/ClassMethods/sanitize_sql_like

def sanitize_sql_like(string, escape_character = "\\")
  pattern = Regexp.union(escape_character, "%", "_")
  string.gsub(pattern) { |x| [escape_character, x].join }
end

sanitize_sql_likeを使って 先ほどの処理が

Hogehoge.where('name LIKE ?', "%#{sanitize_sql_like(args[:name])}%") 
scope :by_name, ->(name) {
  where(arel_table[:name].matches("%#{sanitize_sql_like(name)}%"))
}

の用に書くことができます。 便利ですね。

Rubyの+=はメソッドじゃない

演算周りの処理をまとめていた時にsendで呼び出せると 綺麗にリファクタリングできるかなとおもい調べていると

1.send(:'+',3)
=> 4
1.send(:'+=',3)
NoMethodError: undefined method `+=' for 1:Fixnum

NoMethodErrorになってしまったのですが、Google先生に聞いいてみてもなかなかみつけにくかったのですが、

Rubyのリファレンスの演算子式の自己代入に記載がありました。

演算子式 (Ruby 2.0.0)

&&, ||以外は

  式1 = 式1 op 式2 

に置き換わるそうです。 基本的なところなんですね。。

Rubyの便利メソッド Kernel#Array

Kernel#Arrayは引数で受け取ったものを配列に変換してくれるメソッドなのですが、 意外に便利です。 引数で受け取ったいろいろなオブジェクトを配列にして返却してくれます。

module function Kernel.#Array (Ruby 2.2.0)

試してみると

Array(nil) #=> []
Array("fefe") #=> ["fefe"]
Array(11) #=> [11]
Array([1,2,3]) #=> [1, 2, 3]
Array({key: :value, key2: :value2}) #=> [[:key, :value], [:key2, :value2]]
Array(1..10) #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

rdocでは

Returns arg as an Array.

First tries to call to_ary on arg, then to_a.

arg に to_ary, to_a のいずれのメソッドも定義されていない場合は 一要素の配列 [arg] を返します

となっているので

メソッドの中身は以下のようなものになってるはず。(推測)

object.respond_to?(:to_ary) ? object.to_ary : object.to_a

RailsActiveSupportでもArray#wrapがあり

似たようにArrayを返却してくれるメソッドがあり、こちらは

Array.wrap(nil) #=> []
Array.wrap("fefe") #=> ["fefe"]
Array.wrap(11) #=> [11]
Array.wrap([1,2,3]) #=> [1, 2, 3]
Array.wrap({key: :value, key2: :value2}) #=> [{:key=>:value, :key2=>:value2}]
Array.wrap(1..10) #=> [1..10]

返却される内容はKernel#Arrayとはすこし違っています。

ちなみにwrapの中身は

def self.wrap(object)
  if object.nil?
    []
  elsif object.respond_to?(:to_ary)
    object.to_ary || [object]
  else
    [object]
  end
end

となっています。

RangeやHashが引数に設定されていた場合の挙動が違っているので注意が必要ですが、

使い方に応じて呼び出すと処理がスッキリして使い勝手がいいですね。

メニューバーがスッキリしてアプリが確認しやすいBartenderいらず

メニューバーにアプリが増えてくると

選択中のアプリのメニューが多いものになると隠れて大変ですね。

www.macbartender.com

Bartenderはまとめて拡張メニューのようなものが追加されて使えますね。

Try for 4 weeks

ということでしばらく使っていたのですが、

お試し期間が終わり購入しようかなと思ったら

Buy Now for $15

って15ドル。。

別時ケチる気はないのですが、、

15ドルだったらもうちょっといいアプリあるんじゃないかなと思い調べてみると

apple-products-fan.seesaa.net

これいいですね。

逆転の発想!?

Shift+スペースは半角入力で使っているので少しまだ慣れないのですが、 設定で変更もできるのでしばらく試しながら使っていこうかと思います。

MacでMySQLのサービスの起動停止

MacMySQLサービスの上げ下げはあまりしないのでよく忘れます。 brewでインストールしてると/usr/local/bin/にmysql.serverを作ってくれるそうです。

-> % which mysql.server
/usr/local/bin/mysql.server
-> % mysql.server stop
Shutting down MySQL
.... SUCCESS!

-> % mysql -uroot
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

-> % mysql.server start
Starting MySQL
. SUCCESS!

あまり動かしてないのでよく忘れますね。。 間違ってserviceコマンド叩いてしまう。。

Railsバージョンアップメモ

4.2系も続けてバージョンアップされているので ココらへんでメモ

やることは

  • Gemfileのrailsバージョン変更
  • bundle update
  • bundle install
  • ./bin/rake rails:update
  • テストを流してエラー箇所を修正

bundle updateはまとめて gemのバージョンを上げてしまうので、 上げたくないものは事前にGemfileの書き方を変更しておいたほうがいいかもしれない。

テストはrspec、minitestになるかとおもわれるが どちらにしてもバージョンアップを考えると整備してるほうが比較的簡単にバージョンアップできる。 もう少し整備しないといけないかな。