ホーム ブログ ページ 52

RailsのgeneratorでMultiple migrationsとなる件の対応方法

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Railsのgeneratorでmigrationが二つ以上ある時の対策をしました。

Railsのgenerator対応のプラグインを作成している時に、migrationが二つ以上あるとdb:migrateに失敗してしまいます。

エラーの内容は以下のとおりです(一部伏せています)。

bash-3.2$ script/generate xxx_payment -f XxxPayment
      exists  app/models/
      exists  config/initializers/
      exists  spec/controllers/
      exists  spec/factories/
       force  app/models/xxx_payment_plugin.rb
      create  app/models/xxx_payment_results.rb
   identical  config/initializers/xxx_payment_cart_controller_extend.rb
       force  spec/controllers/xxx_cart_controller_spec.rb
       force  spec/factories/xxx_payments.rb
      exists  db/migrate
      create  db/migrate/20100831124224_create_xxx_payment_plugins.rb
      exists  db/migrate
      create  db/migrate/20100831124224_create_xxx_payment_results.rb
bash-3.2$ rake db:migrate
(in /Users/btm/develop/elecoma/devel_git)rake aborted!
Multiple migrations have the version number 20100831124224
(See full trace by running task with --trace)

このように二つのmigrationが同じ日付になっているため、「Multiple migrations have the version number」となってしまうのです。

では、対策をしてみましょう。実際のところ、時間の取り出しはnext_migration_stringというメソッドで行われているようです。

# rails-2.3.5/lib/rails_generator/commands.rb
          def next_migration_string(padding = 3)
            if ActiveRecord::Base.timestamped_migrations
              Time.now.utc.strftime("%Y%m%d%H%M%S")
            else
              "%.#{padding}d" % next_migration_number
            end
          end

結局のところ、Time.nowのタイミングをずらせばよいというのがわかります。

なので、generatorでは以下のように書けばOKです。

# xxx_payment_generator.rb
class XxxPaymentGenerator < Rails::Generator::NamedBase
  default_options :skip_migration => false

  ...
  def manifest
    record do |m|
      ...
      # migration
      # migration
      unless options[:skip_migration]
        m.migration_template 'create_xxx_payment_plugins.rb', 
                             'db/migrate', 
                             :assigns => {}, 
                             :migration_file_name => "create_xxx_payment_plugins"
        m.sleep 1
        m.migration_template 'create_xxx_payment_results.rb', 
                             'db/migrate', 
                             :assigns => {}, 
                             :migration_file_name => "create_xxx_payment_results"
      end
      ...
    end
  end
end

m.migration_template 同士の間に “m.sleep 1 “として一秒間ずらしてあげます。

では、作成してみましょう。

bash-3.2$ script/generate xxx_payment -f XxxPayment
      exists  app/models/
      exists  config/initializers/
      exists  spec/controllers/
      exists  spec/factories/
   identical  app/models/xxx_payment_plugin.rb
   identical  app/models/xxx_payment_results.rb
   identical  config/initializers/xxx_payment_cart_controller_extend.rb
   identical  spec/controllers/xxx_cart_controller_spec.rb
   identical  spec/factories/xxx_payments.rb
      exists  db/migrate
      create  db/migrate/20100831131456_create_xxx_payment_plugins.rb
      exists  db/migrate
      create  db/migrate/20100831131457_create_xxx_payment_results.rb

Versionが一つずれて作成されているのがわかります。これで、無事マイグレートができるようになりました。

同じエラーではまった人は参考にしていただけると幸いです。

文字数の違う複数の項目をliタグを使って綺麗に並べるTips

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

フォームの選択項目をliタグとcssのfloat、min-width、white-spaceを使って綺麗に並べるTipsです。

登録フォームを動的に作っていると、選択項目がとにかく多い!という事態に遭遇します。

静的なら1つずつtdで切って、文字が長ければcolspanで〜とできるわけですが、
動的に出してるとそういう細かい芸当は無駄にややこしいので、
できるだけ手軽に、できるだけ見栄えよく並べるために、リストタグを活用します。

並べたい項目は以下の通り。

  • たぬきうどん
  • きつねそば
  • 天丼
  • 鶏ガラしょうゆラーメン
  • 特選月見そば
  • みそラーメン
  • 明太子スパゲッティ
  • ざるそば
  • もりそば
  • ナポリタン
  • 森のきのことじゃこの和風スパ
  • ざるうどん
  • ペペロンチーノ

縦に並べるとページが長くなってしまうので、横に並べる事にします。
cssはこんなカンジ。

li {
float: left;
margin-right: 5px;
}

  • たぬきうどん
  • きつねそば
  • 天丼
  • 鶏ガラしょうゆラーメン
  • 特選月見そば
  • みそラーメン
  • 明太子スパゲッティ
  • ざるそば
  • もりそば
  • ナポリタン
  • 森のきのことじゃこの和風スパ
  • ざるうどん
  • ペペロンチーノ

なんとなく見づらい。
文字数がバラバラなので、揃えたいけど一番短いのが2文字、長いのは14文字。
とりあえず14文字にあわせてみます。

li {
float: left;
margin-right: 5px;
width: 14em;
}

  • たぬきうどん
  • きつねそば
  • 天丼
  • 鶏ガラしょうゆラーメン
  • 特選月見そば
  • みそラーメン
  • 明太子スパゲッティ
  • ざるそば
  • もりそば
  • ナポリタン
  • 森のきのことじゃこの和風スパ
  • ざるうどん
  • ペペロンチーノ

だいたい良くなりました。
贅沢言うと右が空きすぎて、そこに詰められればもうちょっと長さを節約できそう。
平均して6文字くらいに収まる項目が多そうなので、6文字分の幅にしてみます。
このときpxで指定するよりもemで指定する方が直感的で調整しやすいのでemを使います。

li {
float: left;
margin-right: 5px;
width: 6em;
}

  • たぬきうどん
  • きつねそば
  • 天丼
  • 鶏ガラしょうゆラーメン
  • 特選月見そば
  • みそラーメン
  • 明太子スパゲッティ
  • ざるそば
  • もりそば
  • ナポリタン
  • 森のきのことじゃこの和風スパ
  • ざるうどん
  • ペペロンチーノ

右の方空間は無駄にならなくなったけど、ちょっと困った状態になりました。
6文字以上ある場合は、幅に応じて伸びて欲しい。
そこでmin-widthを使ってみます。
min-widthはIE6では対応されないので、IE6用のハックも併記して、
幅も自由に伸びるようにwhite-spaceも書いておきます。

li {
float: left;
margin-right: 5px;
width: auto;
min-width: 6em;
white-space: nowrap;
}
* html .sample5 li { width: 6em; }

  • たぬきうどん
  • きつねそば
  • 天丼
  • 鶏ガラしょうゆラーメン
  • 特選月見そば
  • みそラーメン
  • 明太子スパゲッティ
  • ざるそば
  • もりそば
  • ナポリタン
  • 森のきのことじゃこの和風スパ
  • ざるうどん
  • ペペロンチーノ

長いものは文字数に応じて伸びるようになりました。
6文字幅だと普通に並べたのとあんまりかわらない…ので、もうちょっと調整します。

li {
float: left;
margin-right: 5px;
width: auto;
min-width: 9em;
white-space: nowrap;
}
* html .sample5 li { width: 9em; }

  • たぬきうどん
  • きつねそば
  • 天丼
  • 鶏ガラしょうゆラーメン
  • 特選月見そば
  • みそラーメン
  • 明太子スパゲッティ
  • ざるそば
  • もりそば
  • ナポリタン
  • 森のきのことじゃこの和風スパ
  • ざるうどん
  • ペペロンチーノ

綺麗にならびました。

ちなみに今回のようにliタグがfloatするときは、無駄になってもいいからとにかくulタグのclassにclearfixを入れておきます。
#clearfixについては以前の記事を参照

これでエンジニアに複雑な条件分岐をお願いする必要もなくなるので、
みんな幸せになれそうです。

iPhoneのメールアドレスはPC、携帯どちらの入力欄に入力するのか

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

サイトを作って行く上でパソコンのメールアドレス、携帯のメールアドレスそれぞれを入力することがありますが、iPhoneのメールアドレスをどちらに入力させるのかについて調査してみました。

まず前提として、通常の携帯で受信時はiPhoneからのメールはPCから送信されたメールと同様の扱いになります。

そのため携帯でPCからのメールアドレスを受信拒否していると、iPhoneからのメールを受信できません。

前提から考えると結論は「iPhoneのメールアドレスはPCメールアドレス欄に入力する」となるわけですが、使用目的やメールマガジンのレイアウト等を考えると携帯の欄に入力して欲しい気持ちがあります。

そこで、他サイトがどのようにiPhoneのメールアドレスの入力チェックをしているのかを調べてみました。

■某新卒就職サイト

パソコン ○   モバイル ×

■某検索サイト

パソコン ○   モバイル ×

■某総合ショッピングサイト

パソコン ○   モバイル ×

■某グルメ情報サイト

パソコン ×   モバイル ○

■某ブランドECサイト

パソコン ○   モバイル ×

前提通り、基本的にはパソコンのメールアドレスとして対応していることが分かりました。

また、 PCサイトとモバイルサイトで必須項目が異なる場合(PCはPCアドレスが必須、モバイルはモバイルアドレスが必須)はiPhoneでサイトを見るとPCサイトが表示されるため、PCアドレスに入力させないとPCを持っていないiPhoneユーザが会員登録出来ないなどといった問題も発生することが考えられます。

特にルールとかがない現状、メールアドレスの使用目的に合せ、サイト開発者または運営者が判断するしかないようです。

PHP+PEARでデータをExcelファイルに出力する。 Spreadsheet_Excel_Writer Plugin編

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちは、KBMJの中平@PHPエンジニアです。
*最近はPHPで開発を行っていますのでPHPのプラグインについて紹介します。
今回紹はPHPでデータをExcelファイルに出力する方法ついて書きます。

よく、Webシステムでデータをファイルに出力する際にはCSV形式で出してしまう事が多いと思いますが、

CSV データをExcelで開くと、「001234」というデータの場合、頭ゼロが消されてしまい「1234」と数値として表示されてしまう事があるため、CSVではなくExcel形式で出力させてほしいという要望はないでしょうか?

そこで、今回はPHPで簡単にデータをExcelファイルとして出力することができる、Spreadsheet_Excel_WriterというPEARのpluginの使い方について書こうと思います。

環境

OS : Windows Vista

PHP : 5.1.6
PEARを利用します。

Spreadsheet_Excel_Writerのインストール

 //Spreadsheet_Excel_Writerはbeta版なので、
beta版をインストールさせるための設定を行う。


pear config-set preferred_state beta

 インストールpear install Spreadsheet_Excel_Writer-0.9.2

Spreadsheet_Excel_WriterのExcel出力のサンプルコード

 require_once ‘Spreadsheet/Excel/Writer.php’;
class excele_writer
{
     $workbook = new Spreadsheet_Excel_Writer();
        $file_name=’sample.xls’;
        $tablename = sprintf(“establishment_entry_%s”, date(“Ymd”));
        $worksheet =& $workbook->addWorksheet($tablename);

        $format =& $workbook->addFormat();
//excelのフォントを指定 MS UI Gothic 
        $format->_font_name = mb_convert_encoding(“MS UI Gothic”, “shift_jis”);

     $worksheet->writeString(0,0,mb_convert_encoding(‘hogehoge’,”SJIS”,”UTF-8″)); // セルに書き込み
    $worksheet->writeString(0,1,mb_convert_encoding(‘0123456’,”SJIS”,”UTF-8″)); // セルに書き込み
    $workbook->send($file_name);
        $workbook->close();
}

説明

mb_convert_encodingはUTF-8の文字コードをSJISに変換しています。
excelでは日本語はSJISでないと文字化けを起こしますので注意!
writeStringの第一引数はエクセルの行、第二引数は列になっています。

writeStringは文字列を書き込むメソッドなので、数値を文字列として書き込むためexcelで開いたときに頭の0が消えません。

複数データを出力する場合はループさせればOK
sendでファイルに出力
closeでファイルを閉じています。

後はブラウザでアクセスすればexcelファイルが出力されます。


また、Spreadsheet_Excel_Writerだとexcel出力方法も細かく設定できます。

 セルに色をつけたり、文字サイズの変更、罫線、数値のフォーマット指定、画像貼り付け等excelでできることは大抵できるようです。

詳しくはこちらのマニュアルを参考にしてください。

Spreadsheet_Excel_Writer マニュアル
http://pear.plus-server.net/package.fileformats.spreadsheet-excel-writer.html

このSpreadsheet_Excel_Writerというpluginは簡単に導入できてコードも数行で済みますので、PHPからCSVではなくExcel形式でデータ出力したい場合には試してみてはいかがでしょうか?

tortoisegitでclone実行時に「Network error: Connection timed out」のエラーが表示され失敗する(WindowsXP)

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

gitでプロジェクトを管理することになったので、tortoisegitを入れてみました。

cloneを実行してプロジェクトを落とそうとしたとき、PuTTY Fatal Errorがでて失敗したので、

その時の解決方法です。

環境

WindowsXP

TortoiseGit 1.5.2.0

git version 1.7.0.2.msysgit.0

PuTTY 0.60-JP_Y-2007-08-06

ちなみに、

PuTTY Fatal Error 「Network error: Connection timed out」

のエラーダイアログの「OK」ボタンを押すと↓のようなエラーが表示されました。

git.exe clone --progress -v  "ssh://プロジェクトURL" "C:\Documents and Settings\sakuma85\workspace\test"

Initialized empty Git repository in C:/Documents and Settings/sakuma85/workspace/test/.git/
fatal: The remote end hung up unexpectedly

原因はputtyのデフォルト設定にありました。解決方法は以下の通りです。

1.レジストリエディタを開く

 ・Winキー+Rで「ファイル名を指定して実行」ダイアログを開く

 ・「regedit」と入力し「OK」ボタンを押す

2.Puttyセッションを保存しているパスを開く

 ・HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\Sessions

3.「Default%20Settings」をリネームする

 ・「Default%20Settings」を右クリックしメニューから「名前の変更」を選択

 ・「Default Settings」に修正する

これで無事、cloneができるようになりました。

rvmで外部ライブラリもインストール

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

OpenSSLをアップデートしたところ、地味に面倒な事になってしまいました。

railsプロジェクトを新規作成しようとした矢先です。

% rails test
/Users/hachinen/.rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/i686-darwin10.3.0/digest/md5.bundle: dlopen(/Users/hachinen/.rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/i686-darwin10.3.0/digest/md5.bundle, 9): Library not loaded: /opt/local/lib/libcrypto.0.9.8.dylib (LoadError)
  Referenced from: /Users/hachinen/.rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/i686-darwin10.3.0/digest/md5.bundle
  Reason: image not found - /Users/hachinen/.rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/i686-darwin10.3.0/digest/md5.bundle
        from /Users/hachinen/.rvm/rubies/ruby-1.8.7-p249/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
        from /Users/hachinen/.rvm/gems/ruby-1.8.7-p249/gems/activesupport-2.3.6/lib/active_support/dependencies.rb:156:in `require'
        from /Users/hachinen/.rvm/gems/ruby-1.8.7-p249/gems/activesupport-2.3.6/lib/active_support/dependencies.rb:521:in `new_constants_in'
        from /Users/hachinen/.rvm/gems/ruby-1.8.7-p249/gems/activesupport-2.3.6/lib/active_support/dependencies.rb:156:in `require'
        from /Users/hachinen/.rvm/gems/ruby-1.8.7-p249/gems/rails-2.3.6/lib/rails_generator/generators/applications/app/app_generator.rb:3
        from /Users/hachinen/.rvm/rubies/ruby-1.8.7-p249/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
        from /Users/hachinen/.rvm/rubies/ruby-1.8.7-p249/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
        from /Users/hachinen/.rvm/gems/ruby-1.8.7-p249/gems/activesupport-2.3.6/lib/active_support/dependencies.rb:156:in `require'
        from /Users/hachinen/.rvm/gems/ruby-1.8.7-p249/gems/activesupport-2.3.6/lib/active_support/dependencies.rb:521:in `new_constants_in'
        from /Users/hachinen/.rvm/gems/ruby-1.8.7-p249/gems/activesupport-2.3.6/lib/active_support/dependencies.rb:156:in `require'
        from /Users/hachinen/.rvm/gems/ruby-1.8.7-p249/gems/rails-2.3.6/lib/rails_generator/spec.rb:17:in `klass'
        from /Users/hachinen/.rvm/gems/ruby-1.8.7-p249/gems/rails-2.3.6/lib/rails_generator/lookup.rb:140:in `instance'
        from /Users/hachinen/.rvm/gems/ruby-1.8.7-p249/gems/rails-2.3.6/lib/rails_generator/scripts/../scripts.rb:31:in `run'
        from /Users/hachinen/.rvm/gems/ruby-1.8.7-p249/gems/rails-2.3.6/bin/rails:19
        from /Users/hachinen/.rvm/gems/ruby-1.8.7-p249/bin/rails:19:in `load'
        from /Users/hachinen/.rvm/gems/ruby-1.8.7-p249/bin/rails:19

なんかエラーになってしまいました。libsslがないとか言われているので最近何やったっけな…と思ったんですが、そういえばopensslを先日0.9から1.0にアップグレードしてみたのでした。

なのでリンクしていた libcrypto.0.9.8.dylibがなくなってしまい、実行できない状態になってしまってました。

仕方がないのでもう一度 rvm から1.8.7を再インストールしました。が、rvm的な解決方法は他にもある模様で、

rvm update --head 
rvm package install openssl

とするとよいようです。1.9.1を試してみました。あとはrubyを以下のようにインストールします。

rvm install 1.9.1 -C --with-openssl-dir=$HOME/.rvm/usr

他、zlib,readline,iconv,ncursesなど、外部パッケージに依存しそうなものはrvm内でも管理できるようになっているようです。

これならmacportsなどのパッケージ管理システムのアップグレードの度にrubyをコンパイルしなおさずに済みそうで、便利ですね。

はじめてのSQLite(Mac版)

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

SQLiteをはじめて使うレポートです。今回はMac OS Xに標準でインストールされている3.6.23.1での動作となります。(2010/8/6現在の最新バージョンは3.7.0.1)

 SQLiteとは

SQLiteはPostgreSQLやMySqlと同じリレーショナルデータベースですが、

サーバーとしてではなく、単独のアプリケーションとして動作が可能です。

またインストールも簡単で非常にコンパクトなのが特徴です。

 起動と終了

コマンドラインから起動します。

$ sqlite3 
sqlite>

これで起動しました。

終了は以下のコマンドで可能です。

sqlite> .exit

 データベースの作成

では早速データベースを作成してみましょう。

下記のコマンドを入力します。

$ sqlite3 データベースファイル

Mac OS Xの場合、デフォルトのルートディレクトリは /Users/ユーザ名 になっています。

フルパスで指定すると任意のディレクトリのファイルを指定可能です。

また、存在しないデータベースファイルを指定すると新規作成されます。

ここではtest.db というファイル名のデータベースを作成します。

$ sqlite3 test.db

/Users/ユーザ名 配下にファイルが出来ているはずです。

$ ls -al test.db
-rw-r--r--  1 hoge  hoge  0  8  6 20:50 test.db

 データベースへの接続

以下のコマンドで接続できます。

$ sqlite3 test.db 
sqlite>

ちゃんとtest.dbに接続しているかを確認してみましょう。

sqlite> .database
seq  name             file                                                      
---  ---------------  ----------------------------------------------------------
0    main             /Users/hoge/test.db 

 テーブルの作成

下記コマンドで作成します。

sqlite> create table users(id integer, name text);

作成したテーブルの定義を確認してみましょう。

sqlite> .schema users
CREATE TABLE users(id integer, name text);

 レコードの挿入

以下のコマンドを入力します。

sqlite> insert into users values(1, 'hoge');

レコードを参照してみます。

sqlite> select * from users;
1|hoge

簡単ですがひとまずここまで。

次回はもう少し踏み込んだ操作に挑戦しようと思います。

SQLiteをはじめて使うレポートです。今回はMac OS Xに標準でインストールされている3.6.23.1での動作となります。(2010/8/6現在の最新バージョンは3.7.0.1)

 SQLiteとは

SQLiteはPostgreSQLやMySqlと同じリレーショナルデータベースですが、

サーバーとしてではなく、単独のアプリケーションとして動作が可能です。

またインストールも簡単で非常にコンパクトなのが特徴です。

 起動と終了

コマンドラインから起動します。

$ sqlite3 
sqlite>

これで起動しました。

終了は以下のコマンドで可能です。

sqlite> .exit

 データベースの作成

では早速データベースを作成してみましょう。

下記のコマンドを入力します。

$ sqlite3 データベースファイル

Mac OS Xの場合、デフォルトのルートディレクトリは /Users/ユーザ名 になっています。

フルパスで指定すると任意のディレクトリのファイルを指定可能です。

また、存在しないデータベースファイルを指定すると新規作成されます。

ここではtest.db というファイル名のデータベースを作成します。

$ sqlite3 test.db

/Users/ユーザ名 配下にファイルが出来ているはずです。

$ ls -al test.db
-rw-r--r--  1 hoge  hoge  0  8  6 20:50 test.db

 データベースへの接続

以下のコマンドで接続できます。

$ sqlite3 test.db 
sqlite>

ちゃんとtest.dbに接続しているかを確認してみましょう。

sqlite> .database
seq  name             file                                                      
---  ---------------  ----------------------------------------------------------
0    main             /Users/hoge/test.db 

 テーブルの作成

下記コマンドで作成します。

sqlite> create table users(id integer, name text);

作成したテーブルの定義を確認してみましょう。

sqlite> .schema users
CREATE TABLE users(id integer, name text);

 レコードの挿入

以下のコマンドを入力します。

sqlite> insert into users values(1, 'hoge');

レコードを参照してみます。

sqlite> select * from users;
1|hoge

簡単ですがひとまずここまで。

次回はもう少し踏み込んだ操作に挑戦しようと思います。

Railsの処理の中でRakeのタスクを実行する方法

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

 今回はRailsの処理の中でRakeのタスクを実行する方法を紹介したいと思います。

 実行したいRakeのタスク名が「hoge:huga」だったとすると以下のコードになります。

Rake::Task.new(‘hoge:huga’, Rake.application).invoke

 基本Rakeのタスクを処理の中で実行するということはほぼないかと思いますが、Rakeのタスクのテストしたい時にテストコードの中で実行できたら便利かと思います。

 Railsの環境は、1.2.6、2.3.8で確認しました。2.3.8の場合は事前に「require ‘rake’」する必要があります。

Google Analyticsにおいて見落としがちなポイント

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちは。アクセス解析チームのNASAです。 第2回目の今回は、Google Analyticsを設定、活用していく中で見落としがちなポイントをご紹介します。

今回なぜこのテーマになったかというと、今までアクセス解析チームでは100以上のサイトを見てきましたが、5社に2社は設定が間違っているという統計があります。

自分の会社の設定は大丈夫と思っている方も、もう一度設定を確認してみてください。

———————————————————————————

見落としがちなポイント その1 :自社アクセスの除外設定

 ⇒Google Analyticsの設定の際にきちんと自社や関係者からのアクセス数は除外するように設定されていますか?

これを除外していないと正確なユーザー数は把握することが出来ず、また正確な数値の推移も追うことができません。

除外設定は以下のところで設定可能です。

1・ログイン後、プロファイルが表示された下にフィルタマネージャーという項目があるので、

  そこをクリックします。

アクセス元フィルタ用

2・クリックして、新しいフィルタマネージャの作成を選択します。

   ①フィルタ名に任意のフィルタ名を設定します。

   例)社内アクセス除外

  ②適用するプロファイルを選択し、右側に移動させ追加ボタンを押します。

  ③すべて設定が終わったら、変更を保存を押して完了です。

マネージャフィルタ用

見落としがちなポイント その2 : タイムゾーンの設定

⇒タイムゾーンは最初はデフォルトで太平洋が選択されております。
  太平洋にしてしまうと16時間の時差が出てきてしまいます。
  これにより・・・

   ・ 時間帯別で見た場合に、アクセスが少ないはずのところが多くなっている
   ・メルマガを打った直後のアクセス数が少ない

   など、細かい分析をする際には支障が出てきてしまいます。   そのためにも、タイムゾーンについては、最初の設定の際に

  ”東京”

  に合わせておくことが必要です。

  タイムゾーンの設定は以下から可能です。

①Google Analyticsの画面にログインした際に下記のような画面があります。

  その中にある”アカウント設定を編集”をクリックします。

②クリックすると下記の画面が表示されます。
 その中のデフォルトの国を”日本”に設定します。

③最後に変更を保存をクリックして設定が完了です。

※各プロファイルごとに行う場合は、各プロファイルの右側にある編集ボタンから行うことが可能です。

※Adwordsと連携している場合は、Adwordsの設定が優先されますのでご注意ください。

——————————————————————————–

今回は最近よく見かける見落としがちなポイントについて2つだけですが、書いてみました。

それでは失礼します。

JMeterで役立つTips

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちはダオカです。

今回は負荷テストで個人的に使う機会が多い、JMeterの役に立ちそうなTipsをいくつか紹介したいと思います。

一定時間リクエストを送り続ける設定の仕方

負荷テストではよく「5分間リクエスト送り続けてのレスポンス状態をみる」といったような一定時間リクエストを送り続けるようなテストが行われます。

JMeterでそのようなシナリオを作成するには、スレッドグループのスケジューラを利用します。

設定方法

1. ループ回数を無限に設定する

2. 「スケジューラ」のチェックボックスをチェックする

3. スケジューラ設定の「持続時間 (秒)」にリクエストを送り続けたい秒数を入力する。

備考

・スケジューラ設定の開始時刻、終了時刻は入力必須になっていますが、過去の日付にしておけば無視されるので特段の理由がなければ、初期値のままでかまいません。

サンプラーのホスト名をいちいち書き換えるのが面倒くさい時

負荷テストでははじめにステージング環境で試してみて、その後本番環境で行ったりすることがあったりします。

こういう場合、本番環境とステージング環境でホスト名が違っていて、ホスト名の部分を書き換えないといけない場合があります。

これが1ページならいいのですが、複数ページにわたる場合、いちいちサンプラ毎に書き換えていては、面倒くさい、どっかで漏れや間違えが生じてしまうなど効率がよくありません。

このような時には「HTTPリクエスト初期値設定」という設定エレメントを利用すると便利です。

このHTTPリクエスト初期値設定では、ホスト名やポート番号、プロトコルなどの初期値を設定することができます。

これで、複数ページにわたるテストでもいちいちサンプラ毎にホスト名を書き換えるという面倒くさいことから解放されます。

ただし、HTTPリクエスト初期値で設定した値はサンプラーで上書きすることが可能です。

なので、サンプラーで初期値を利用したい箇所は、その箇所を空欄にしておく必要があります。

逆に、初期値を利用したくない場所はサンプラーでその項目の部分を設定すれば、サンプラーの値で設定した値が利用されます。

Basic認証がかかったページをテストしたい

何らかの事情でBasic認証がかかったページでも、JMeterでテストを行うことができます。

JMeterでBasic認証がかかったページをテストしたいときは、「HTTP 認証マネージャ」を使用します。

1. スレッドグループで右クリックし、「追加」→「設定エレメント」→「設定エレメント」→「HTTP 認証マネージャー」をクリックし、HTTP 認証マネージャを追加する。

2. 基底URLにBasic認証がかかるURL、ユーザ名、パスワードを入力する。

Cookieを使いたい

セッション情報の保持などにCookieがよく使われますが、JMeterでCookieを利用したサイトのテストを行いたいときは、「HTTP クッキーマネージャ」を使用します。

「HTTP クッキーマネージャ」はスレッドグループに追加するだけで利用できます。

何らかの事情で意図した値を保持したいということがなければ、特に設定は必要ありません。

ユーザエージェントを変えたい

モバイルやスマートフォンのサイトのテストを行う場合、ユーザーエージェントを設定しないとテストできない場合があります。

このようなケースでは、「HTTP ヘッダマネージャ」を利用します。

ユーザエージェントの設定例

1. スレッドグループで右クリックし、「追加」→「設定エレメント」→「設定エレメント」→「HTTP ヘッダマネージャ」をクリックし、HTTP ヘッダマネージャを追加する。

2. HTTP ヘッダマネージャの追加をクリックし、名前に「User-Agent」、値に適当なユーザーエージェントの値(例ではiPhone4の値)を設定する。

※HTTPヘッダマネージャでは、ユーザーエージェントのみでなく、HTTPヘッダで設定する値の変更をすることが可能です。

リクエストが自分の意図した結果通りのものか確認したいとき

JMeterではサンプラでリクエストを投げて、レスポンスにかかった時間を測定したりしますが、そのレスポンスが自分の意図したものでないとテストの意味がありません。

自分がシナリオ作成段階で、自分の意図した状態でレスポンスが返っているかどうか確認する手段として、リスナーの「結果をツリーで表示」をよく利用しています。

このリスナーではリクエスト毎の、リクエスト内容、レスポンス結果、応答データが詳細に表示されます。

ここで応答データをみると、自分が意図したレスポンス内容かどうか確認できます。

最近リリースされた、JMeter2.4ではいままであった、テキスト表示、簡易的なHTMLレンダリングに加え、XMLパーサ、JSONパーサ、正規表現の取り出しテストの機能も加わって、結構強力な機能になっています。

携帯サイトのアクセス判別方法とセッションハイジャック

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

携帯サイトのアクセス判別方法とセッションハイジャック

こんにちは、でりくーです。

携帯サイトへのアクセス判別方法と、 セッションID漏洩の問題点を簡潔に調べた範囲でまとめてみた。

■携帯からのアクセスの判別方法

携帯からのアクセスであることを判別するために、

1. アクセス元がdocomo、au、softbankの各キャリアで使用しているIPアドレス帯域であること

2. User-Agentによる認証 の2点を併用する方法がある。

1.の補足

携帯からインターネットにアクセスする場合は、

一度各キャリアのゲートウェイを通り、 その後、インターネットを通じて各携帯サイトにつながる。

つまり、アクセス元のIPアドレスは各キャリアのIPアドレスとなるため、

IPアドレスとキャリアのマッピングデータがあれば,キャリアを判別することができる。

ちなみに、各主要キャリアのIPアドレス帯域は公式サイトで確認できる。

■docomo

http://www.nttdocomo.co.jp/service/imode/make/content/ip/

■au

http://www.au.kddi.com/ezfactory/tec/spec/ezsava_ip.html

■softbank

http://creation.mb.softbank.jp/web/web_ip.html

○セッションハイジャックについて

Webアプリケーションとブラウザの間でやり取りされるセッションIDが第三者に知られてしまうと、

その第三者も正規ユーザとまったく同じアクセスを手にすることができる。

他人のセッションIDの値を何らかの方法で突き止め、

それを自分で使うことによって他人のセッションの続きを横取りするのがセッションハイジャックである。


 参考にしたサイト

■【PHPで作る】初めての携帯サイト構築

http://gihyo.jp/dev/serial/01/mobilesite-php/0002

■携帯電話向けWebアプリケーションのセッション管理手法

http://d.hatena.ne.jp/ockeghem/20070224

■セッション乗っ取り

http://thinkit.co.jp/free/tech/7/4/1.html

■Webアプリケーションに潜むセキュリティホール

http://www.atmarkit.co.jp/fsecurity/rensai/webhole03/webhole01.html

Seasar2でCSV処理

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

お久しぶりです。wryyyです。

今回のエントリーは、前回に続き、Seasar2のプロジェクトである、
S2CSVを紹介したいと思います。

(今回もSeasar2かい!って話は置いといて。。。)ここを参考におはなしを進めてまいります。

では、まずは、お決まり(?)の

s2CSVとは何か!?

S2CSVはSeasarとアノテーションを使ってCSVファイルや
CSVデータを手軽に扱うためのライブラリ。

S2CSVでは以下の事が可能になるようです。

・CSVファイル と Java Objectの相互変換を簡単に行える
・CSV個別の設定ファイルが必要ない
・バリデーションを行うことが出来る
・バリデーションメッセージ定義はStrutsライクでなじみがある形式

業務で、CSVファイルを読み込んだり、書き込んだりするのがまだまだあるこのご時世
Seasar2に慣れた方であれば、
このライブラリを使えばサクサクっと開発できることと思います。

(このライブラリがないと、
書き込みであれば、StringuBufferに何個もデータを突っ込んでやら、
読み込みであれば、InputStreamやらなんやら使ってゴニョゴニョしたりと色々面倒です。)

では早速、設定と動作に関して説明しましょう。

S2CSVの設定と動作

まずは、ココからS2CSVのjarファイルをダウンロードしましょう。

ダウンロードしたjarファイルをクラスパスに追加してください。

続いて、diconファイルを設定していきます。以下のdiconファイルに追記していってください。

・app.dicon





・creator.dicon





・customizer.dicon





以上で、設定は完了となります。

続いて、実際のコードの説明に移ろうと思います。

が!!!

実際、自分もこのライブラリに関してはまだ触ったことがないので、

コードの説明に関してはまた次回にしたいと思います。

Seasar2でCSVの書き込み、読み込みをおこないたい場合は、
ぜひ、このライブラリを使用してみてはいかがでしょうか。

モバイルアクセス解析から検索シェアを見る

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

今回は、モバイルアクセス解析から検索エンジンのシェアを見ていきます。
PCサイトに比べ、解析もSEOも難しいモバイルサイトの実情を探ります。

どうもです。アクセス解析チーム アソウリュウタロウです。

最近はモバイル解析の担当案件が増えていて、仕事中ずっとケータイをいじくり回していることもしばしば。滅多に使わなかった自分のケータイは、いまや過酷な使用環境ゆえに充電器と繋がりっぱなしです。

モバイルアクセス解析の現状

いまのところ、モバイルアクセス解析は難題です。

現状では無料アクセス解析ツールではまともな解析は難しいでしょう。
Google Analyticsは、2010年2月に公式ブログでモバイル対応をアナウンスされましたが、実際のところ未だにまともな数字は取れそうにありません。
無料ツールでは「うごくひと2」「myRTmobile」など、いくつか数値が見られるツールも出てきてますが、PCサイトに比べればまだまだ発展途上な分野かと思います。

さて、そんなモバイル解析環境ですが、解析だけでなくSEOなども対策がしづらいことでも有名です。PCサイトほど評価項目が多くなく、各施策に対する効果や危険性があまり明確化されていないのです。

そもそも大前提として、ユーザーがキャリア公式を使っているのか、YahooやGoogleといったモバイル版検索エンジンを使っているのかすら定かではないので、対策が取りづらいといったことも言えます。

というわけでちょっと調べてみました。

任意の期間における検索エンジンユーザーのエンジン別比率

強いのはキャリア公式

弊社のお客様のいくつかのモバイルサイトから数値を抽出し、平均値にまとめています。

i-mode(docomo)はリファラー情報が取れない機種が多いため、あくまでも参考値にしかなりませんが、EZweb、SoftBankでは公式メニュー検索エンジンが非常に強くなっているのが分かります。

特にSoftBankのYahoo率は非常に高く、通常の検索だけでなく画像検索なども含めて、98%の使用率となっています。

ある機関によるアンケート結果では、公式メニューの検索の使用率は約40%といった結果が出ていましたが、その数値ともだいぶ乖離があります。

コンテンツやターゲット層など、サイトによっても大きく結果が変わってくる可能性はありますが、この数値を見る限り、キャリア公式メニューの使用率は高く、それだけ公式サイト優勢の現状は揺るがないと言えそうです。

■AppiritsのGoogle アナリティクスセミナー

AppiritsのGoogle アナリティクスセミナーは、初期設定から機能解説、仕組の理解までさまざまな内容を用意しています。
ご興味のある方は是非弊社セミナーにご参加ください。

Google アナリティクス セミナー インターフェイス編
Google アナリティクスのレポート画面が把握できていない方向けの講座。
レポート画面の解説や既存機能の活用法、マルチチャネルなどの新レポートのインターフェイスを解説します。

Google アナリティクス セミナー 分析手法編
インターフェイスは把握しているが、数値の意味や考え方がよく分からないという方向けの講座です。 アクセス解析を用いた課題抽出やサイト改善の考え方を解説します。

Google アナリティクス セミナー 徹底設定編
現状のGoogle アナリティクスで取得可能な数値に物足りない方向けの講座。
外部サイトへの誘導やソーシャルボタン連携、eコマース機能などのカスタマイズ方法をレクチャーします。

エラーページ(404.html)をGoogleAnalyticsで計測する方法

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

アクセス解析チーム中林です。

こんにちは。

今日はHTTPステータスコード404のエラーページを

GoogleAnalyticsで取得する方法のご紹介をします。

最近はGoogleAnalyticsの非同期タグが

推奨されるようになって、サイトをみていても

よく見かけてくるようになってきました。

でもまだ、非同期タグに移行できなかったりする方も

多くいるかと思いますので

今日は、404エラーページをGoogleAnalyticsでトラッキングする方法を

埋め込んでいるタグの形式に合わせてご紹介しますね。

まず非同期のトラッキングコードから・・・

■ga.js(非同期タグ)

<script type="text/javascript">var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXX-X']);
_gaq.push(['_trackPageview', '/404.html?page=' + document.location.pathname + document.location.search + '&from=' + document.referrer]);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();</script>

次にちょっと前の同期しているトラッキングコード

■ga.js(非同期タグではないタグ)

<script type="text/javascript">
var gaJsHost = [1]"https:" == document.location.protocol) ? " https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + " google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E";
</script>
<script>
try{
var pageTracker = _gat._getTracker("UA-xxxxx-x");
pageTracker._trackPageview("/404.html?page=" + document.location.pathname + document.location.search + "&from=" + document.referrer);
} catch(err) {}
</script>

最後に旧トラッキングコードです。

■urchin.jsの場合

<script type="text/javascript" src="http://www.google-analytics.com/urchin.js">
</script>
<script type="text/javascript">
_uacct = "xxxxx-x";
urchinTracker("/404.html?page=" + _udl.pathname + _udl.search);
</script>

404エラーページのトラッキングコードに設置してみてください。

しばらくするとデータが溜まりますので、

「コンテンツ > 上位のコンテンツ」の検索ボックスで

「page\=\/404」と入力すると、

どこからやってきたのか?

(検索エンジンなら)どうゆうキーワードで来たのか?

なんてことがわかるようになります。

↓こんな感じです。

ぜひ試してみてください。

ではでは、失礼しましたー。

KBMJ GoogleAnalyticsのスクールも開催中です!

Google Analyticsスクールでは、セミナーやブログではお伝えしきれない細かな設定方法やアクセス解析手法について、徹底的に解説いたします。

少人数のスクール形式だから、状況やレベルに合わせてインタラクティブに、より詳しく、実用的な活用術を徹底指導いたします!

KBMJ GoogleAnalyticsのスクールも開催中です!

Google Analyticsスクールでは、セミナーやブログではお伝えしきれない細かな設定方法やアクセス解析手法について、徹底的に解説いたします。

少人数のスクール形式だから、状況やレベルに合わせてインタラクティブに、より詳しく、実用的な活用術を徹底指導いたします!

References

References
1 "https:" == document.location.protocol) ? " https://ssl." : "http://www."); document.write(unescape("%3Cscript src='" + gaJsHost + " google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"

git-svnによる実プロジェクトでのチーム開発 (2)

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちは、SHIMADAです。

今回は、git-svnを使って上流のSVNリポジトリと同期をとりながら開発を進めていく方法について紹介します。

 前提

前回のエントリと同様にSVNリポジトリのクローンがローカルに作られている状態から説明します。

 上流との同期

SVN側にコミットされた他のメンバーのコードをローカルに取り寄せるコマンドを二つ紹介します。

git-svn-fetch

はじめに、リポジトリ全体の同期を取るコマンドです。

$ git svn fetch

これは、trunkとすべてのブランチにコミットされた変更をローカルに取り込みます。

取り込まれる先は、 .git/ 以下にあるローカルのリポジトリです。

$ git branch -a

で表示される、 remotes/svn/ 以下のブランチが最新の状態にアップデートされます。

git-svn-rebase

次に、現在チェックアウトしているブランチとワーキングファイルを同期するコマンドです。

$ git svn rebase

このコマンドを実行するには条件があり、ローカルでの変更がすべてコミットされた状態でなければなりません。

前回のおさらいになりますが、下記のような操作になります。

$ git add app/models/user.rb
$ git commit -m "svnとgit-svnのテスト"

もしコミットしない状態でgit-svn-rebaseを実行しようとすると、

$ git svn rebase                                                                                                                                                       
app/models/user.rb: needs update
update-index --refresh: command returned error: 1

という感じでエラーになりますので、間違えてローカルでの作業内容が消えてしまうということはありません。

 超便利なgit-log

git-svn-rebaseが成功すると、リモートでの変更がマージされた状態となり、ワーキングツリーも更新されます。

どのような変更が加わったかを見るには、

commit 0a5c6053915709f0872655099236c3ecbb28dadc
Author: shimada <shimada @bc2c4182-fb10-4788-ac18-b0505eda9c62>
Date:   Wed Jul 21 18:51:51 2010

    svnとgit-svnのテスト
    
    git-svn-id: https://example.com/svn/repos/myproj/branches/new_feature@123 bc2c4182-fb10-4788-ac18-b0505eda9c62

というコマンドでログを見ることができます。

git-svn経由で取得されたコミットには git-svn-id: というSVNのリビジョンを表す一行が表示されます。

また、SVNの場合は svn log -v というオプションで、リビジョンごとに変更されたファイルのリストが表示されましたが、gitの場合はさらに強力で、git log -p というオプションをつけるとコミットごとの変更内容をunified-diffの形で見ることができます。

commit 0a5c6053915709f0872655099236c3ecbb28dadc
Author: shimada <shimada @bc2c4182-fb10-4788-ac18-b0505eda9c62>
Date:   Wed Jul 21 18:51:51 2010

    svnとgit-svnのテスト
    
    git-svn-id: https://example.com/svn/repos/myproj/branches/new_feature@123 bc2c4182-fb10-4788-ac18-b0505eda9c62

diff --git a/app/models/user.rb b/app/models/user.rb
index df685f1..77efc53 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -4,7 +4,7 @@ class User < ActiveRecord::Base
 
   def test
-    "this is test"
+    "this is test for svn and git-svn"
   end
 

これを使うと、コミットログを流し見するだけで、他のメンバーがどんな変更を行ったか概略を掴むことができます。

 コンフリクトとその解消

git-svn-rebaseの途中でローカルのコミットとのコンフリクトが検出されると、

$ git svn rebase
        M       app/models/user.rb
r123 = 6c10697b941ac5537d12b94a206a89fa540fc062 (svn/new_feature)
First, rewinding head to replay your work on top of it...
Applying: svnとgit-svnのテスト
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging app/models/user.rb
CONFLICT (content): Merge conflict in app/models/user.rb
Failed to merge in the changes.
Patch failed at 0001 svnとgit-svnのテスト

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".

rebase refs/remotes/svn/new_feature: command returned error: 1

というメッセージが表示されてrebaseの動作が一時停止されます。

コンフリクトを起こしたファイルを確認してみます。

$ git st
app/models/user.rb: needs merge
# Not currently on any branch.
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       unmerged:   app/models/user.rb
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       .gitignore
#       config/database.yml
#       log/
no changes added to commit (use "git add" and/or "git commit -a")

「unmerged:」と表示されているファイルがコンフリクトしたファイルです。

なお、コンフリクトマーカーはSVNとほぼ同じ形式で、

<<<<<<< HEAD
    "this is test"
=======
    "this is test for git-svn"
>>>>>>> svnとgit-svnのテスト

となっています。上半分がSVNのHEADの状態、下半分がローカルの状態です。

ローカル側のマーカーの後ろにはコミットメッセージが表示されています。

編集して、コンフリクトを解消したら、

$ git add ファイル名

で解消したことをGitに伝えた後、

$ git rebase --continue

でrebaseが再開されます。(このコマンドは上の方で引用したコンフリクト時のメッセージに出てきます。)

 上流へのコミット

SVNリポジトリの変更を取り込んだあと、コードに問題がなければローカルの変更をSVNリポジトリにコミットします。

$ git svn dcommit
Committing to https://example.com/svn/repos/myproj/branches/new_feature ...
        M       app/models/user.rb
Committed r124
        M       app/models/user.rb
r124 = 0a5c6053915709f0872655099236c3ecbb28dadc (svn/new_feature)
No changes between current HEAD and refs/remotes/svn/new_feature
Resetting to the latest refs/remotes/svn/new_feature
app/models/user.rb: locally modified
        M       app/models/user.rb
Committed r125
        M       app/models/user.rb
r125 = 5b080870f969045ab0787170fc06001908c7b0bb (svn/new_feature)
No changes between current HEAD and refs/remotes/svn/new_feature
Resetting to the latest refs/remotes/svn/new_feature

こんな感じで、ローカルでのコミットがひとつずつSVNのチェンジセットとして送信され、リビジョン番号が振られていきます。コミットメッセージもGitに登録されているものがそのまま送られます。

git-svn-rebaseを忘れて、あるいは他のメンバーのコミットを気づかずににgit-svn-dcommitを行ってしまった場合、Gitがリモートの更新を検出し、事前に git-svn-rebase を実行してくれるので、ローカルの古い状態でSVNリポジトリを上書きしてしまうということは起こりません。

しかし、Gitはテキストベースでのマージとコンフリクト検出以上のことはできないので、コードが正常に動作する状態でコミットされたという保証がありません。

マージされた変更の内容を確認して、問題があればメンバーに連絡して、リポジトリへのアクセスを一時控えてもらうなどの措置が必要です。

 まとめ

git-svnを使った開発のサイクルは、

  1. コードを書く
  2. 細かい作業の区切りごとにgit-commitでバージョン管理する
  3. 大きな区切り(機能をひとつ実装した!など)でSVNにコミットする
    1. git-svn-rebaseでローカルブランチを最新のものに更新する
    2. コンフリクトがあれば解消する
    3. git-svn-dcommitでコミットする
    4. はじめに戻る

という感じになります。

コードが不安定な状態でも、ローカルへのコミットでチームに迷惑をかけずにバージョン管理ができるgit-svnはかなり便利です。

みなさんも是非トライしてみて下さい。

日本語のRailsプロジェクトを中国語化する

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Railsプロジェクトは基本的にUTF8のcharsetで、多言語を対応していますが、 Railsのプロジェクトを中国語化にするにはアプリ上にもいくつか変更必要がある箇所があります。

ここで基本的な箇所をリストにします。

1.charset
一般的にRails日本語のプロジェクトのcharsetはUTF-8ですので、そのままで結構です。
中国語のGB2312に変更したい場合、viewsファイル(html.erb、rhtml)のヘッダmetaの

charset指定の「charset=UTF-8」

「charset=GB2312」
に変更

2.validateチェック
・日本語に特有なvalidateチェックはカタカタのチェックです。
カタカナチェックをすべて外しか、英数字のチェックに変更する必要があります。
・郵便番号桁数
日本に郵便番号が7桁ですので、中国の6桁に変える必要があります。

3.エラーメッセージ
エラーメッセージは下記のディレクトリにあります。
config\locales
ja.yml→エラーメッセージ
activerecord:
    errors:

translation_ja.yml→エラー項目名

この2ファイルをzh.yml,translation_zh.ymlに変更するか、
あるいはこのディレクトリにzh.yml,translation_zh.ymlを追加するか。
どちらでも構いません。

renameする場合、ja.ymlの最初に「ja:」という定義がありますので、
それを「zh:」に変更すればOK。

4.環境設定ファイル
config\environment.rbファイルにタイムゾーンとロケールの指定を変更
config.active_record.default_timezone = ‘Tokyo’


config.i18n.default_locale = ‘ja’

config.i18n.default_locale = ‘zh’

5.メール
メールあたりは変える箇所が何か所があります。

・設定ファイルに定義がある場合、GB2312かUTF8に変更してください。
config\environments\production.rb
日本語プロジェクトのメールのエンコードは
ActionMailer::Base.default_charset = ‘iso-2022-jp’

・一般的にメール送信処理はapp/models/notifier.rbが行います。
GetText.locale = ‘ja’
@@charset=’iso-2022-jp’

@mail.subject = NKF.nkf(‘-j’, @mail.subject)
@mail.body = NKF.nkf(‘-j’, @mail.body)

上記の分を中国語に向いているようにしてください。
NKF.nkfのオプションには中国語のエンコードがないようですので、UTF8に変更するか、
NKF.nkfをやめるかをお勧めします。


6.DB
DBもcharsetの話ですね。サイトはGB2312の場合、DBも対応のcharsetに変更してください。


まとめ、Railsのプロジェクトを中国語化にするには基本的にcharset+validateの変更。
charsetはUTF8のままでしたら、もっと簡単です。

キャリアごとのクローラ-

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

先日、自分が見ているサイトのあるページのアクセス数を見てたら、極端にアクセス数が増えてるページがあって、「何だろう…」と思ってちょっと調べてみたら、

「i-robotなんちゃら」っていうアクセスが10000近く。。。これは何だろうと調べてみたら、「モバイルのクローラ-」だそうで、、、

各キャリアごとにどんなクローラ-があるのか、ちょっと眺めてみると

■DoCoMo
・i-robot
トップページ(ドコモに申請した際に着地用に設定したページ)からクローラ-が行けるページならどこまでも見に行くみたいで、さらに日によって気まぐれなのかアクセス数が2ケタの日もあれば、その100倍になったりするときもあります。。。

■au
・KDDI-Googlebot-Mobile
いろいろ調べてみると公式サイトのみ見に来るらしい。でも、アクセスはトップページのみっぽいし、だいたい決まった時間に訪問しに来ます。

■SoftBank
・Y!J-SRD/1.0
・Y!J-MBS/1.0
こちらもアクセスは1日1回くらいで、だいたい決まった時間に来てくれてるみたいです。J-SRDはたまにトップ以外も見てるけど何か違いがありそう…

他にもGooglebot-Mobile(Googleモバイル。結構頻繁に遊びに来る)とか、SoftBankMobileSearch(Yahooケータイ)等のクローラがあるようです。しかし、他にも見慣れないクローラがアクセスしに来ていたりします。

アクセス数を自前で集計するような機能を作ってる際は、このクローラ分も考えて作らないとかなりの誤差が出るのかと改めて痛感しました。。。

FlashLite Tips – フォーカスを任意の順番で制御する

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。


こんにちは。エンジニアの はる です。
今回はFlashLiteのTipsとして、FlashLiteでフォーカスを任意の順番で制御する方法についてご紹介したいと思います。(※サンプルファイル有り)

まずは、FlashLiteにおけるボタンのフォーカス仕様についてご説明します。

FlashLiteにおけるボタンのフォーカス仕様

図のようにステージにボタンが配置されている場合、
・下キーを数回押した場合:「1→2→3→4→5→1→2→…」
・上キーを数回押した場合:「5→4→3→2→1→5→4→…」
上記のように、”左から右、上から下”という順序でフォーカスが制御され、表示範囲外にあるボタン6は無視されます。

また、FlashLite1.1は、
・ボタンオブジェクトにインスタンス名を設定できない
・on(keyPress “”) や on(keyPress “”) 等で上下キーのイベントを取得することができない
といった仕様になっています。

こういった仕様・制限を考慮すると、
・上記のボタン制御順に縛られずにフォーカスを与えたい場合(※日本地図上の都道府県を選択するUIにしたい、等…)
・Flash内で画面スクロールを実装する等、表示範囲外のボタンを制御したい場合
・条件によって、ボタンの数や位置が変動する場合
上記のようなUIを実装する場合に一手間の工夫が必要となり、そこで、”擬似ボタン”を使用する方法がよく用いられています。

擬似ボタンとは?

擬似ボタンとは、ムービークリップにrollOver、rollOut時の表示パターンを設定することで擬似的にボタンのように見せる方法です。

それでは、擬似ボタンの実装方法について下記で具体的に解説していきます。

STEP 1:隠しボタン(※ボタンオブジェクト)の作成

(1) _rootのタイムラインの1フレーム目に下記のフレームアクション記述します。

stop();

//fromBtn、toBtnの初期化
/:fromBtn = 0; //選択されていた隠しボタンの番号
/:toBtn     = 0; //新たに選択した隠しボタンの番号

(2) _rootタイムライン上にボタンオブジェクトを3つ作成します。 

(3) 各ボタンオブジェクトのアクションに下記を記述します。(※ボタン毎にtoBtnに設定するIDを変更してください。)

on(rollOver){
  /:fromBtn = /:toBtn;
  /:toBtn = 1; //ボタン毎にIDを設定する
  call("rollOver");
}

ここでは、1, 2, 3 というIDをそれぞれのtoBtnの値として設定することとします。

(4) _rootタイムラインにラベル名を”rollOver”に設定したキーフレームを用意します。 

(5) rollOverラベルのフレームアクションに下記を記述します。

// fromBtn=0 は、初期表示時のフォーカスがどのボタンにも無い状態を示しています。
/*** 下キー判定 ***/
if [1]/:fromBtn==0 && /:toBtn==1)||
    (/:fromBtn==3 && /:toBtn==1)||
    (/:fromBtn==2 && /:toBtn==3)||
    (/:fromBtn==1 && /:toBtn==2{
    /:status = "down";
}
/*** 上キー判定 ***/
if [2]/:fromBtn==0 && /:toBtn==3)||
    (/:fromBtn==1 && /:toBtn==3)||
    (/:fromBtn==2 && /:toBtn==1)||
    (/:fromBtn==3 && /:toBtn==2{
    /:status = "up";
}

/*** 下キーが押された場合の処理 ***/
if(/:status eq "down"){
  trace("hoge");
}
/*** 上キーが押された場合の処理 ***/
if(/:status eq "up"){
  trace("fuga");
}

これで上キー・下キーが押された際のイベントを取得し、それに応じた処理を実行することができるようになります。

STEP 2:擬似ボタン(※ムービークリップ)の作成

擬似ボタンとなるムービークリップの実装方法は様々ありますが、参考までに私が以前に行った方法をご紹介します。

(1) _rootタイムライン上に表示上ボタンとして見せたいムービークリップを作成します。

 ・1フレーム目にフォーカスが当たっていない際の表示を設置します。
 ・2フレーム目にフォーカスが当たった際の表示を設置します。
 ・フレームアクションは1フレーム目、2フレーム目ともに「stop();」のみです。

 ■1フレーム目:フォーカスが当たっていない場合の表示

 ■2フレーム目:フォーカスが当たっている場合の表示

(2) それぞれのムービークリップに”フォーカスを当てたい順”にインスタンス名を命名します。
今回は、ムービークリップの表記通り、”mc◯”という形式でインスタンス名をそれぞれ命名することとします。

(3) _rootのタイムライン1フレーム目のフレームアクションに「focusNoの初期化」を追記します。

stop();
//fromBtn、toBtn、focusNoの初期化
/:fromBtn = 0; //選択されていた隠しボタンの番号
/:toBtn     = 0; //新たに選択した隠しボタンの番号

/:focusNo = 0; //現在フォーカスが当たっている擬似ボタンの番号

(4) _rootタイムラインにラベル名を”focus”に設定したキーフレームを用意します。 

(5) focusラベルのフレームアクションに下記を記述します。

buttonSize = 5; //ボタン数を設定
oldFocusNo   = /:focusNo; //選択されていた擬似ボタンの番号
newFocusNo   = /:focusNo; //新たに選択した擬似ボタンの番号

if(/:status eq "up"){
  //最上位の擬似ボタンから最下位の擬似ボタンにフォーカスを移す
  if (oldFocusNo <= 1){
    newFocusNo = buttonSize;
  }else{
    newFocusNo = oldFocusNo - 1;
  }
}else if(/:status eq "down"){
  //最下位の擬似ボタンから最上位の擬似ボタンにフォーカスを移す
  if (oldFocusNo >= buttonSize){
    newFocusNo = 1;
  }else{
    newFocusNo = oldFocusNo + 1;
  }
}

/:focusNo = newFocusNo;

//選択されていた疑似ボタンのフォーカスをはずす
tellTarget("mc" add oldFocusNo){
  gotoAndStop(1);
}
//新たに選択した疑似ボタンにフォーカスを与える
tellTarget("mc" add newFocusNo){
  gotoAndStop(2);
}

(6) rollOverラベルのフレームアクションからfocusをcallするように修正します。

/*** 下キーが押された場合の処理 ***/
if(/:status eq "down"){
  call("focus");
}
/*** 上キーが押された場合の処理 ***/
if(/:status eq "up"){
  call("focus");
}

これで表示上は擬似ボタンがrollOver、rollOutをしているように見えるようになり、任意の順番でフォーカスを与えることができるようになります。

STEP 3:拡張について

今回ご紹介するのはここまでとなりますが、上述の仕組みをベースに
・on(press)時の制御
・擬似ボタンを動的に表示/非表示
・Flash内でのスクロール処理・ポップアップ処理
等々…の拡張を行うことができます。興味のある方は是非是非チャレンジしてみてください。

サンプル

・Flash8形式:focus_sample_fl8.fla をダウンロードする

・FlashCS3形式:focus_sample_cs3.fla をダウンロードする

・FlashCS4形式:focus_sample_cs4.fla をダウンロードする

References

References
1 /:fromBtn==0 && /:toBtn==1)|| (/:fromBtn==3 && /:toBtn==1)|| (/:fromBtn==2 && /:toBtn==3)|| (/:fromBtn==1 && /:toBtn==2
2 /:fromBtn==0 && /:toBtn==3)|| (/:fromBtn==1 && /:toBtn==3)|| (/:fromBtn==2 && /:toBtn==1)|| (/:fromBtn==3 && /:toBtn==2

rails の model メソッドを簡単に daemon 化する方法

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Rails で普段開発される方は、 ruby script/console や ruby script/runner は非常に重宝されていると思います。

これらのコマンドは、Web アプリを作成するために作った model  のメソッドを、簡単に batch や コマンドラインのインタラクティブアプリに変更することが出来、cron 化やデバッグに大変重宝します。

今回、その script/[hoge] に、新たなスクリプトを1つ追加しましたのでご紹介いたします。

今開発中のアプリで、あるバッチを数秒単位で実行する必要がでてきました。

バッチを定期実行するとき、例えば下記のようなシェルファイルを作成し、

#!/bin/sh

RUBY="/usr/local/bin/ruby"
DATE=`date +"%Y%m%d"`

cd [RAILS_ROOT]

$RUBY script/runner -e production "ModelClass.method" >> /var/tmp/model_method.${DATE}.log 2>&1 &

そのファイルを cron に登録して実行することがよくあることかと思います。

ですが cron の最小実行単位は「分」のため、秒の間隔でのアクセスは上記の

script/runner を使った方法では行えません。

通常、秒単位での実行を行いたい場合、下記のような「sleep」を用いた処理を書くのが良く行われます。

例えばこのような Rails の model ファイルを作成し、

class ModelClass <  ActiveRecord::Base
  SLEEP = 5
  class << self
    def method
      loop do
        time = Time.now.strftime("%H:%M %S")
        self.core time
        sleep SLEEP
      end
    end

    def core(time)
      open("#{RAILS_ROOT}/log/test_log.txt", "a") do |f|
        f.write(time + "\n")
      end
    end

  end
end

ターミナル上で

$ ruby script/runner -e production ModelClass.method

を実行すると、log/test_log.txt に 5秒毎に現在の時刻が書き込まれる処理が実行されます。

問題は、この処理を永続化したい場合です。

その場合、上記の処理を daemon 化する必要があります。

daemon についてはこちら

http://markun.cs.shinshu-u.ac.jp/learn/linux/h_06.html

Rubyではスクリプトを簡単にdaemon化する処理が既に用意されているのですが(http://homepage1.nifty.com/~tetsu/ruby/tool/daemon.html)、ActiveRecord の支援を受けたいと考えた自分は、「より Rails らしい」 daemon プロセスの作成法を考えてみました。

使うのは、 gem daemons です

http://daemons.rubyforge.org/

mongrel が依存している gem なので、Rails を使う多くの方々は知らず知らずのうちにインストールしていることと思われます。

そして下記の内容のファイルを作成し、[RAILS_ROOT]/script/daemon という名前で保存します。

require File.dirname(__FILE__) + '/../config/boot'
require 'rubygems'
require 'daemons'

Daemons.run(
  "#{RAILS_ROOT}/script/runner",
  :app_name => "rails_daemon",
  :dir_mode => :script,
  :dir => "../log",
  :multiple   => true,
  :keep_pid_files => false
)

オプションの意味については、詳しくは下の参考文献を参照くださいませ。

そして、ターミナル上で、実行したい処理を下記のように実行します。

$ ruby script/daemon start -- -e production ModelClass.method

(「–」だけ忘れないで下さい)

すると、ModelClass.method の中身が、「rails_daemon」というプロセス名で、daemonとして実行されます。

$ ps ax | grep rails_daemon
 1685   ??  S      0:01.90 rails_daemon                                          
 1690 s002  R+     0:00.00 grep rails_daemon

終了するときは下記になります。

$ ruby script/daemon stop

今のオプションでは、daemon はオプションを変えて複数プロセス作成できますが、上のコマンドでその全てが終了します。

上記のファイルを作成することにより、Rails の model のメソッドを、その内部を一切変更することなく、Rails 使いの方々が慣れ親しんだ文法で、daemon プロセス化することが可能になりました。

こちらの daemon は多重起動ができる設定にしているため、渡すメソッドによって、様々な処理をそれぞれ daemon プロセス化することができます。また、ARGV をうまく指定することにより、daemon プロセス名もより分かりやすいものに変えることもできるでしょう。

もっとシンプルに指定が出来る daemon を作成したい場合、例えば、

require File.dirname(__FILE__) + '/../../config/boot'
require 'rubygems'
require 'daemons'

def daemon_run(running_command, mode = "run", rails_env = "production", daemon_name = nil)
  if daemon_name.nil?
    daemon_name = running_command
  end
  argv = [mode, "--", "-e", rails_env, running_command]
  Daemons.run(
    "#{RAILS_ROOT}/script/runner",
    :ARGV => argv,
    :app_name => daemon_name,
    :dir_mode => :script,
    :dir => "../log",
    :multiple   => true,
    :keep_pid_files => false
  )
end

という内容のファイルを [RAILS_ROOT]/lib/daemons/base.rb という名前で保存し、

require File.dirname(__FILE__) + '/../../config/boot'
require "#{RAILS_ROOT}/lib/daemons/base.rb"

daemon_run("ModelClass.method", "start")

という内容のファイルを [RAILS_ROOT]/lib/daemons/daemon1.rb

という名前で保存したら、

$ ruby [RAILS_ROOT]/lib/daemons/daemon1.rb

で、daemon プロセスを作成できます。(プロセスを止めるときは、 kill する必要がありますが)

※追記

daemon の、run / start / stop が可能なようにしました。

[RAILS_ROOT]/lib/daemons/rails.rb

require File.dirname(__FILE__) + '/../../config/boot'
require 'rubygems'
require 'daemons'

def daemon_run(running_command, mode = "run", rails_env = "production", daemon_name = nil, prefix = "Prefix::")
  if daemon_name.nil?
    daemon_name = running_command
  end
  argv = [mode, "--", "-e", rails_env, running_command]
  Daemons.run(
    "#{RAILS_ROOT}/script/runner",
    :ARGV => argv,
    :app_name => prefix.to_s + daemon_name.to_s,
    :dir_mode => :script,
    :dir => "../log",
    :multiple   => true,
    :keep_pid_files => false
  )
end

[RAILS_ROOT]/lib/daemons/daemons1.rb

require File.dirname(__FILE__) + '/../../config/boot'
require "#{RAILS_ROOT}/lib/daemons/base.rb"

type = "start"
if ARGV[0] && ["start", "stop", "run"].index(ARGV[0])
  type = ARGV[0]
end

daemon_run("ModelClass.method", type)

参考文献

http://labs.unoh.net/2007/10/daemons.html

http://daemons.rubyforge.org/classes/Daemons.html#M000004

Redmineはnginx+Passengerで

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

私はRedmineを自分のMacに入れてますが、ちょっとお試しって気分なだけなのにApacheが動作しちゃうのは少し大袈裟な気がしていました。

なので軽量といわれる nginx(エンジンエックス) でもっと手軽に動作させられないかな…と試した際のメモを書いときます。

とはいえ、先にやっている人がいて、こことかに書いてある事が殆どです。

MacPortsやRubyの環境はまず整えておいてください。今回MacPortsは使いますので。また、Redmine自体は${HOME}/redmine 配下にインストールしておくものとし、データベースはSqlite3を使用します。

 1 ImageMagick及びRMagickのインストール

sudo port install ImageMagick
gem install rmagick

 2 Passengerをインストール

gem install passenger

Passengerのインストール先を確認します。ここで出てくるパスは後ほど必要になります。

passenger-config --root

 3 nginxのインストール

普通にnginxをインストールしたいところですが、これだとPassengerを組み込む際にうまくいかないので先にnginxのPortfileを編集します。

cd /opt/local/var/macports/sources/rsync.macports.org/release/ports/www/nginx
sudo vim Portfile

ファイルの末尾へ行き、以下の行を追加しましょう

variant passenger description {Adds passenger support} {
    configure.args-append   --add-module=${手順2で確認したパス}/ext/nginx
}

この状態でnginxのインストールを行います。

sudo port install nginx +gzip_static +passenger +ssl

 4 nginxの設定

cd /opt/local/etc/nginx
sudo cp mime.types.example mime.types
sudo cp nginx.conf.example nginx.conf

次にnginx.confを編集します。

sudo vim nginx.conf

変更した点は以下の通りです。

    gzip  on; # デフォルトでコメントアウトされているので外す

次に82行目あたりに以下のような記述を加えます。

 81     passenger_root ${手順2で出力されたパス};
 82     passenger_ruby /Users/yourname/.rvm/rubies/ruby-1.8.7-p249/bin/ruby;
 83     passenger_max_pool_size 8;
 84     passenger_max_instances_per_app 1;
 85     passenger_pool_idle_time 3600;
 86     
 87     server {
 88         listen 80;
 89         client_max_body_size 250M;
 90         server_name redmine.local;
 91         root /Users/yourname/redmine/public;
 92         passenger_enabled on;
 93         rails_env production;
 94     }

※ここでは redmine.local というホスト名を127.0.0.1として/etc/hostsに定義しているものとします。

 5 nginxの自動起動設定

MacPorts1.9からは以下のような簡略記法が取り込まれたようです。楽ですね。

sudo port load nginx

これで、 http://redmine.local というホスト名にブラウザからアクセスするとRedmineの画面が確認できるかと思います。

Windows7ユーザにおすすめするキャプチャのやり方

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

仕事で使うパソコンが新しくなりまして、Windows7になりました。
Windows7では色々なところが新しくなっているようです。
よくわかりませんが、1つ大変便利なソフトが標準でインストール
されているので紹介します。

なにか資料などを作るとき、画面のキャプチャが必要なタイミングが
よくあると思いますが、Windowsではキャプチャをとるステップは面倒な
ものでした。「Print Screenしてペイントに貼り付けて保存」面倒です。

Winshotなどのキャプチャソフトを使っていた人もいるかもしれませんが、
WIndows7ユーザの方には「Snipping Tool」がおすすめです。

Windows7に標準でついてくるこのソフトはこのような機能があります。
1.キャプチャ(範囲を矩形選択)
2.キャプチャ画像に直接メモ書き(絵とか文字とか描けます)
3.編集したキャプチャ画像を保存/メール送信/クリップボードへコピー

このようにキャプチャします。

このように編集します

シンプルですが、表示領域をキャプチャして、ここがどうだといった説明を
する時、役立ちツールです。

あとちなみに、領域を選択した時点で画像がクリップボードに格納されるので
直接パワーポイントなどに貼り付け可能です。

Windows7使っている方に是非おすすめなキャプチャソフトSnipping Toolは
スタートメニューのアクセサリの中から起動できます。
あと、デスクトップのキャプチャやタイマー撮影などはできないので、
CapureXPといソフトを併用しています。

あと、Macユーザの方はSkitchというソフトが同じような感じです(多機能)

最近人気な記事