2014年10月27日月曜日

ActiveRecordのvalidate条件に変数を使う

ActiveRecordのvalidateはよく使うのですが、
必ずチェックを行いたいとは限らないので、validate条件を設定したりするときに、
その比較条件に変数を使いたかったので調べました。

まずは普通のvalidate
validates :shop_id,
    presence: true

validate条件を使ったとき
validates :shop_id,
    presence: true, if: "shop_flg == '1'"

マジックナンバー使うのは嫌なので変数(定数)に置き換えてみる
SHOP_FLG = '1'

validates :shop_id,
    presence: true, if: "shop_flg == #{SHOP_FLG}"

判定を文字列にするので、普通に#{}で変数を囲めば実現できるようです。


参考URL
http://www.techscore.com/tech/Ruby/Rails/model/validation/4

2014年10月21日火曜日

rubyの日付処理ではまった件

rubyの日付処理をしようとしてて、不思議な変換がかかってはまってしまった件について。

試したrubyのバージョンはこれです。
$ ruby -v
ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-darwin13.0]

こういうrbファイルを作って実行してみると、こういう実行結果になります。
y = 10001
m = 2
d = 31
h = 0
mm = 0

begin
  puts Time.local(y, m, d, h, mm, 0)
  rescue
    puts 'error1'
end

begin
  puts DateTime.parse("#{y}-#{m}-#{d} #{h}:#{mm}:00")
rescue
  puts 'error2'
end

実行結果
10001-03-01 00:00:00 +0900
error2
Time.localに存在しない日を入れても、次の月の月初に変換してしまうようです。

Time.localに入れる日(d)を32にしてみると、結果が変わります。
y = 10001
m = 2
d = 32
h = 0
mm = 0

begin
  puts Time.local(y, m, d, h, mm, 0)
  rescue
    puts 'error1'
end

実行結果
error1
日として取りうる値が1-31だから、31まではエラーにならないようですね。
とりあえず日付のチェックはDateTime#parseで実装してしまいました。
Timeのソース見てないけどちゃんと見てみた方がよいかもですね。。

2014年10月13日月曜日

railsでテキストフォームに日付のフォーマットを行って初期値を入れる

railsでMySQLから取得した値をテキストフォームの初期値に入るようにしていたら、 日付のフォーマットをする必要があったのでそのときに調べたものです。 railsのバージョンはこちら。
$ bundle exec rails -v
Rails 4.1.5
MySQLのテーブルのデータはこうなっています。
mysql> select start_date from mst_services where mst_service_id=28;
+---------------------+
| start_date     |
+---------------------+
| 2014-09-22 10:36:00 |
+---------------------+
1 row in set (0.01 sec)
フォームにそのまま出力するとこんな感じ。
<%= form_for(@mst_service) do |f| %>
  <%= f.text_field :start_date, class: 'form-control' %>
<% end %>

# => 2014-09-22 10:36:00 +0900
日付のフォーマットを指定してみました。 valueにstrftimeしたものを入れるようにしたらよいようです。
<%= f.text_field :start_date,value:f.object.start_date.try(:strftime,'%Y-%m-%d %H:%M'), class: 'form-control' %>

# => 2014-09-22 10:36

2014年10月10日金曜日

railsでoctopus使ってたら起動直後にエラー出る件

railsでmaster-slave構成のDBサーバと接続するのにoctopusを使ってみたのですが、
unicornで複数プロセスをforkさせるようにしていると、
プロセスのfork直後にoctopusが以下のエラー吐いてたので対応調べてみました。

以下がエラー内容。
どうやらDBへの接続がうまくいってないようです。
一発目の実行時だけで、その後はエラー出ないのでfork直後にだけ起こるようです。
NoMethodError: undefined method `query' for nil:NilClass: SHOW FULL FIELDS FROM `mst_services`

config/unicorn.rbに以下を記述するとエラー出なくなりました。
after_fork do |server, worker|
    ActiveRecord::Base.connection_proxy.instance_variable_get(:@shards).each {|k,v| v.clear_reloadable_connections! }
end


参考URL
https://github.com/tchandy/octopus/issues/59