• 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
 

 RSpecで現在時刻に関連するテストをするときに、Rails4.1からはTimecopを使わなくても ActiveSupport::Testing::TimeHelpers の to_travel というメソッドを使って現在時刻を設定することができます。

 たとえば、下記のように現在時刻を返すメソッドがあるとします。

   1  class Foo
   2    def now
   3      Time.now
   4    end
   5  end

 正しく現在時刻を返しているかのテストは下記のように書けます。

   1  travel_to Time.new(2014, 11, 24, 9, 30, 0) do
   2    foo = Foo.new
   3    expect(foo.now).to eq(Time.new(2014, 11, 24, 9, 30, 0))
   4  end

 travel_toで現在時刻を設定しているので、expectで評価するときに決まった時間を書いて比較できます。

 ですがもしnowメソッドでDateTime.nowを返していると、to_travelでは対応できません。

   1  class Foo
   2    def now
   3      DateTime.now # <- to_travelで設定した時間ではなく現在時刻が返る
   4    end
   5  end

 その場合にはやはりTimecopを使う必要があります。Gemfileには下記のようにgemを追加。

   1  group :test do
   2    gem 'timecop'
   3  end

 テストは下記のように記述します。

   1  Timecop.freeze(Time.new(2014, 11, 24, 9, 30, 0)) do
   2    foo = Foo.new
   3    expect(foo.now).to eq(Time.new(2014, 11, 24, 9, 30, 0))
   4  end

 travel_to が対応しているのは Time.now と Date.today のみのようです。

 travel_to(date_or_time, &block)
 rails4.1からのtravel_toをrspecで使う

posted by Png akanuma on Tue 25 Nov 2014 at 00:00

環境変数によってRailsアプリの動作を切り替えたいことがあって、
nginx + Passenger で動かしているRailsアプリに環境変数を渡す方法を調べました。

nginx の起動スクリプト(/etc/init.d/nginx)に書いても、
/etc/default/nginx に書いてもうまくいかなかったのですが、
nginx の設定ファイルの location ブロックで
passenger_set_cgi_param で設定することで環境変数が設定できます。

   1  passenger_set_cgi_param HOGE fuga;

これでRailsアプリの中で ENV['HOGE'] で "fuga" という値が取得できるように なります。

参考ページ
16.3.5. Phusion Passengerが提供するアプリケーション
8.6.1. passenger_set_cgi_param

posted by Png akanuma on Sat 22 Nov 2014 at 14:13

Rails4で入力フォームから日時を選択できるように datetimepicker を使ったのですがちゃんと動くまでに軽くはまったのでメモ。

bootstrap3-datetimepicker-rails

まずはGemfileに下記エントリを追加して bundle install

   1  gem 'momentjs-rails'
   2  gem 'bootstrap3-datetimepicker-rails'

moment と datetimepicker のJavaScriptファイルを読み込むための設定を追加します。 私は coffeescript を使っているので application.js.coffee に下記エントリ を追加します。 bootstrapの設定が入っていない場合はあわせて追加します。

   1  #= require bootstrap
   2  #= require moment
   3  #= require bootstrap-datetimepicker

続いてstylesheetの設定も追加します。 私の場合は scss を使っているので、application.css.scss に下記を追加。 ちなみに順番もこの通りじゃないとちゃんと動きません。

   1  @import "bootstrap-sprockets";
   2  @import "bootstrap";
   3  @import "bootstrap-datetimepicker";

ここまででひとまずの下準備は終了なので、実際にdatetimepickerを適用したい部分の作業をします。 今回の対象のView部分は下記のような感じです。

   1  <div class="form-group">
   2    <div class="col-md-2">
   3      <%= f.text_field :start_datetime, value: @user.start_datetime, class:
   4  "form-control", id: "user_start_datetime" %>
   5    </div>
   6  </div>

f.text_field で出力される input タグに対して datetimepicker() メソッドを 実行します。 下記内容でcoffeescriptのファイルを別途作成して読み込みます。

   1  $ ->
   2    $('#user_start_datetime').datetimepicker()

これで入力ボックスを選択した時に日時選択用のポップアップが表示されるようになります。 また、日付のフォーマットのデフォルトは MM/DD/YYYY hh:mm A/PM なので、日本の形式に変更します。 inputタグに data-date-format 属性で指定するのですが、rails の text_field タグでは追加の属性を指定できないため、先ほどのcoffeescriptを変更して動的に属性を追加します。

   1  $ ->
   2    date_format = {'data-date-format': 'YYYY/MM/DD HH:mm'}
   3    $('#user_start_datetime').attr(date_format)
   4    $('#user_start_datetime').datetimepicker()

これで日付フォーマットが変更されます。 今回は一番シンプルな形で datetimepicker を使いましたが、オプションの指定で表示形式などは色々変更できますので、試してみてもらえると良いかと思います。

参考ページ http://eonasdan.github.io/bootstrap-datetimepicker/

posted by Png akanuma on Sat 22 Nov 2014 at 14:02

 VagrantでUbuntu環境を立ち上げようとするとChefでのProvision中にabortするというのが発生していてしばらく原因が分からなかったのですが、名前解決できなかったのが問題だったようです。

 私のケースでは config.vm.box に chef/ubuntu-14.04 を指定して、 chef.run_list では apt, sqlite, redisio などの cookbook を指定した状態で vagrant up すると、下記のようにProvision中にabortしていました。

   1  $ vagrant up
   2  Bringing machine 'default' up with 'virtualbox' provider...
   3  ==> default: Importing base box 'chef/ubuntu-14.04'...
   4  ==> default: Matching MAC address for NAT networking...
   5  〜〜〜中略〜〜〜
   6  ==> default: [2014-11-16T11:51:03+00:00] WARN: Cloning resource attributes for package[tar] from prior resource (CHEF-3694)
   7  ==> default: [2014-11-16T11:51:03+00:00] WARN: Previous package[tar]: /tmp/vagrant-chef-3/chef-solo-1/cookbooks/redisio/recipes/default.rb:23:in `block in from_file'
   8  ==> default: [2014-11-16T11:51:03+00:00] WARN: Current  package[tar]: /tmp/vagrant-chef-3/chef-solo-1/cookbooks/ruby_build/recipes/default.rb:34:in `block in from_file'

 このときVMの状態は abort になります。

   1  $ vagrant status
   2  Current machine states:
   3  
   4  default                   aborted (virtualbox)

 provisionなしでの起動はできるので、試しに再度 vagrant up したあとに vagrant ssh してUbuntuにログインし、 sudo apt-get update してみました。

   1  vagrant@vagrant:~$ sudo apt-get update
   2  0% [Connecting to us.archive.ubuntu.com] [Connecting to security.ubuntu.com]Connection to 127.0.0.1 closed by remote host.
   3  Connection to 127.0.0.1 closed.

 securiy.ubuntu.com に接続しようとしているときに終了してしまっているようです。このときVMはまたaborted状態になります。VM上からインターネットへのアクセスはできていたのですが、どうも名前解決あたりが怪しそうだと思って調べていたところ、下記記事を発見。

Virtual Box ゲストから外部ネットワークにつながらない(解決済み)

 上記サイトで紹介されている通り、config.vm.provider の設定にNAT接続時のDNSの挙動に関連する、natdnshostresolver1、natdnsproxy1 を追加します。

   1    config.vm.provider :virtualbox do |vb|
   2      vb.gui = false
   3      vb.customize ['modifyvm', :id, '--memory', '1024']
   4      vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
   5      vb.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
   6    end

 この設定を追加することで、VM上での名前解決要求がホストマシンのDNSサーバによって行われるようになります。

9.11.5. Enabling DNS proxy in NAT mode

9.11.6. Using the host's resolver as a DNS proxy in NAT mode

 上記設定を追加して一旦 vagrant destroy したあとに vagrant up し直したところ、無事Provisionが完了するようになりました。

posted by Png akanuma on Sun 16 Nov 2014 at 21:15

UITextField の場合

   1    → UITextFieldTextDidBeginEditingNotification
   2      UIKeyboardWillChangeFrameNotification
   3      UIKeyboardWillShowNotification
   4      UIKeyboardDidChangeFrameNotification
   5      UIKeyboardDidShowNotification
   6  

UITextView の場合

 

   1     UIKeyboardWillChangeFrameNotification
   2      UIKeyboardWillShowNotification
   3    → UITextViewTextDidBeginEditingNotification
   4      UIKeyboardDidChangeFrameNotification
   5      UIKeyboardDidShowNotification
   6  

iOS7, iOS8 両方

posted by Face Saturn on Thu 25 Sep 2014 at 18:06

The code below is example which toggles view which covers status bar.

   1  import UIKit
   2  
   3  class
   4  ViewController: UIViewController {
   5  
   6  	var	uWindow:	UIWindow!
   7  	
   8  	@IBAction	func
   9  	Do( AnyObject! ) {
  10  		if uWindow {
  11  			uWindow = nil
  12  		} else {
  13  			uWindow = UIWindow( frame: UIApplication.sharedApplication().statusBarFrame )
  14  			uWindow.backgroundColor = UIColor( white:0, alpha:0.5 )
  15  			uWindow.windowLevel = UIWindowLevelStatusBar + 1
  16  			uWindow.hidden = false;
  17  		}
  18  	}
  19  }
  20  

posted by Face Saturn on Mon 4 Aug 2014 at 18:25

そろそろDroongaをちゃんと使ってみようと思ってますが、 開きっぱなしのブラウザのタブを削減するために書き出しておきます。

posted by Png genki on Wed 30 Jul 2014 at 17:39

ライブラリの内部から素のRuntimeErrorが飛んでくると対処に困りますね。 適当な例外クラスを用意してほしいものですが、とりあえず以下のような関数を定義することで、特定のメッセージの場合だけrescueできます。

   1  def RuntimeError(message)
   2    ($!.is_a?(RuntimeError) and $!.message == message) ? RuntimeError : Class
   3  end
   4  
   5  begin
   6    # do something
   7  rescue RuntimeError('connection closed by server') => e
   8    # ...
   9  end

posted by Png genki on Tue 29 Jul 2014 at 11:01

jQueryで append すると、追加したDOM中のscript タグが実行されます。

   1  $('#target').append(what);

script タグを実行せずに append したい場合、あらかじめ script タグを取り除いておけば ok

   1  what.find('script').remove();
   2  $('#target').append(what);

posted by Png genki on Sun 6 Jul 2014 at 18:07

ActiveRecordのmigrationで change と up/down を同居させるには、 以下のように書けば良いようです。

   1  class DoSomething < ActiveRecord::Migration
   2    def change
   3      #change
   4    end
   5  
   6    def migrate(direction)
   7      super
   8      case direction
   9      when :up
  10        # up
  11      when :down
  12        # down
  13      end
  14    end
  15  end

posted by Png genki on Sun 15 Jun 2014 at 10:02