ActiveRecord覚書
Rails(ActiveRecord)のfindについて自分用の覚書。
- 環境
- モデルの作成
従業員モデルの作成
$ rails generate model employee first_name:string last_name:string birth_date:date sex:string department_id:integer hire_date:date
部門モデルの作成
$ rails generate model department name:string
- 準備:DBの用意
Railsのmigrationを実行し下記のような構造のテーブルを作成しました。
よくあるやつですね。
(migrationによりテーブル作成しているのでcreated_at, updated_at列
も実際のテーブルには付加されています。)
$ rake db:migrate
employeesテーブル(従業員テーブル)
id | ID(主キー) |
first_name | 名 |
last_name | 姓 |
birth_date | 誕生日 |
sex | 性別 |
department_id | 部門ID |
hire_date | 入社日 |
departmentsテーブル(部門テーブル)
id | ID(主キー) |
name | 部門名 |
テーブルができたら適当なデータを5件くらい各テーブルにINSERT。
- findの確認
rails consoleコマンドによりfindの動作を確認。
◎find()メソッド
Employee.find(1) Employee Load (14.6ms) SELECT `employees`.* FROM `employees` WHERE `employees`.`id` = 1 LIMIT 1 => #<Employee id: 1, first_name: "太郎", (略), updated_at: nil>
オブジェクトとして取得できました。
では見つからない場合はどうなるのだろう。
Employee.find(999) Employee Load (0.8ms) SELECT `employees`.* FROM `employees` WHERE `employees`.`id` = 999 LIMIT 1 ActiveRecord::RecordNotFound: Couldn't find Employee with id=999 from /home/sun-rise/.rvm/gems/ruby-1.9.3-p0/gems/activerecord-3.1.3/lib/active_record/relation/finder_methods.rb:339:in `find_one' (略)
例外が投げられる。
◎find_by_***()メソッド
Employee.find_by_id(1) Employee Load (0.2ms) SELECT `employees`.* FROM `employees` WHERE `employees`.`id` = 1 LIMIT 1 => #<Employee id: 1, first_name: "太郎", (略), updated_at: nil>
見つからない場合、
Employee.find_by_id(999) Employee Load (0.3ms) SELECT `employees`.* FROM `employees` WHERE `employees`.`id` = 999 LIMIT 1 => nil
nilが返される。
◎find(:all, :conditions=>[...])メソッド
Employee.find(:all, :conditions => ['id=:id', {:id=>1}]) Employee Load (1.3ms) SELECT `employees`.* FROM `employees` WHERE (id=1) => [#<Employee id: 1, first_name: "太郎", (略), updated_at: nil>]
オブジェクトが配列に格納されている。
見つからない場合、
Employee.find(:all, :conditions => ['id=:id', {:id=>999}]) Employee Load (1.0ms) SELECT `employees`.* FROM `employees` WHERE (id=999) => []
空の配列が返される。
find()メソッド、find_by_***()メソッドには LIMIT 1 が付き、合致するレコードが
複数テーブルに存在していても1件分のオブジェクトが返される。
[Google][Developer][Day][2011] Google Apps Scriptのソースコード
http://code.google.com/intl/ja/googleapps/appsscript/guide.html は、
Googleスプレッドシートやその他のGoogleプロダクトをJavaScriptを用いて制御する仕組みだそうです。
Excelのマクロのようなものでしょうか。
JavaScriptで制御できるというのはいいですね。
問題は、JSONで提供されている都市ごとの日別供給電力と最大消費電力を
Google Apps Scriptでスプレッドシートに展開してください、というものです。
私は、以下の3つの関数を定義して回答しました。
- GET_JSON
- SETUP_SHEET
- SETUP_SHEETS
下記がコードです。
function GET_JSON() { var response = UrlFetchApp.fetch("http://gdd-2011-quiz-japan.appspot.com/apps_script/data?param=4627646934474507351"); var jsonString = response.getContentText(); var jsonObj = Utilities.jsonParse(jsonString); return jsonObj; } function SETUP_SHEET(json) { var usage = 0; var percentage = 0; var dataCount = 1; var city = json.city_name; var sheet = SpreadsheetApp.getActiveSpreadsheet().insertSheet(city); data = json.data; sheet.setName(city); for(var powerIdx in data) { capacity = data[powerIdx].capacity; usage = data[powerIdx].usage; percentage = usage / capacity * 100; sheet.getRange(dataCount, 1).setValue(capacity); sheet.getRange(dataCount, 2).setValue(usage); sheet.getRange(dataCount, 3).setValue(percentage + '%'); dataCount += 1; } } function SETUP_SHEETS() { var json = GET_JSON(); for(var cityIdx in json) { SETUP_SHEET(json[cityIdx]); } }
きちんとスクリプト作成・編集用のツールが用意されていて、スクリプトのデバッグ実行も
できるというスグレモノでした。
# FirefoxだとGoogle Docsが動作しなかったのはなんでだろう・・・。
[Google][Developer][Day][2011] Web Gameのソースコード
毎年恒例のhttp://www.google.com/events/developerday/2011/が今年も開かれます。
今年も入場するためにはDevQuizを解きボーダーラインをクリアする必要があります。
今年は
- ウォームアップクイズ
- クイズ
- 分野別クイズ
- Web Game
- Android
- Google Apps Script
- 一人ゲーム
- チャレンジクイズ
- スライドパズル
という構成となりました。
まず、分野別クイズのWeb Gameを解いてみたのでそのソースコードを記してみます。
Web Gameと銘打っておりますが、いわゆる神経衰弱です。
ということで(?)プログラムで解こうということになるわけです。
Web GameのページにはChrome Extensionのサンプルコード(開いたカードの色を
取得する)が配布されていました。(最初、その存在に気が付いていなかった。)
GoogleさんによるChrome Extensionへの誘いです。どうもありがとうございました。
以下が回答に用いたコードです。
var cardNum = $(".cell").length; var cards = new Array(cardNum); for(var i = 0; i < cardNum; i++) { conc.flip(i); var elm = document.getElementById("card" + i); var color = elm.style.backgroundColor cards[i] = color; } var cardsIdx = new Array(cards.length); for(var j = 0; j < cards.length; j++) { var color = cards[j]; for(var k = 0; k < cards.length; k++) { if(j == k) { continue; } else { if(color == cards[k]) { cardsIdx[j] = k; } } } } $("#answer").val(cardsIdx.join(",")); $("#solve").submit();
このコードをFirebugのコンソールに貼り付けて、問題毎に実行ボタンをポチポチする
という半自動コードです。
Firefox 6.0からはスクラッチパッドが搭載されているのでそれも使えそうですね!
Chrome Extension使ってません。Googleさん、ごめんなさい。
当初は、
- あるカードをひっくり返す。
- それ以降のカードを順々にひっくり返す。
といった総当り的なコードを書こうとしましたが、どうも上手く動作しませんでした。
(コーディングの問題ですね。ええ。)
そこで、せっかく配布してくれているサンプルコードですからダウンロードして
コードを見てみました。
カードの色の取得方法が分かったところで
「いっぺん全部ひっくり返して色を取得してから回答用の配列作ればいんじゃね。」
と思い作ったのが上記のコードです。
全自動にしたい気もしましたが、全64問だったのでそれぐらいのポチポチは勘弁して
やろうということで回答完了。
Cloud Foundryを触ってみる。(デプロイ他)
環境変数を表示するための簡単なアプリケーションを作成し、デプロイしてみます。
Cloud Foundryではアプリケーションのホストやポート番号、インスタンス情報
その他諸々の環境変数はJSON形式でENVに格納されているようです。
今回は数行のアプリケーションを作成・デプロイしてENVの中身を覗いてみたいと思います。
require 'sinatra' require 'pp' get '/' do "<pre>#{ENV.pretty_inspect}</pre>" end
アプリケーションをデプロイするには「vmc push」。
上で作成したRubyスクリプトの置いてある場所で実行してみましょう。
対話形式でアプリケーションをデプロイできます。
$ vmc push Would you like to deploy from the current directory? [Yn]: Y Application Name: アプリケーション名 Application Deployed URL: 'アプリケーション名.cloudfoundry.com'? Detected a Sinatra Application, is this correct? [Yn]: Y Memory Reservation [Default:128M] (64M, 128M, 256M, 512M, 1G or 2G) 64M Creating Application: OK Would you like to bind any services to 'アプリケーション名'? [yN]: N Uploading Application: Checking for available resources: OK Packing application: OK Uploading (1K): OK Push Status: OK Staging Application: OK Starting Application: OK
SinatraアプリかRailsアプリかといった事を自動的に判別してくれるみたいで賢いですね。
注意としては、Application Name で任意にアプリケーション名を入力しますが、
URLのドメイン名にも適用されるのでアンダースコアを含めない方がよいようです。
「Would you like to bind any services to …」はMySQL/Redis/MongoDBのサービスを
アプリケーションにバインドするかどうかの質問事項です。
今回はDBを利用しないのでN。
これでアプリケーションがデプロイされ、http://アプリケーション名.cloudfoundry.com で
アクセスできる状態となりました。
試してみてください。
なお、上記以外のpush方法は次のとおり。
Application Creation push [appname] Create, push, map, and start a new application push [appname] --path Push application from specified path push [appname] --url Set the url for the application push [appname] --instances <N> Set the expected number <N> of instances push [appname] --mem M Set the memory reservation for the application push [appname] --no-start Do not auto-start the application
アプリケーションの停止は「vmc stop アプリ名」、削除は「vmc delete アプリ名」で行います。
その他にもログなどのアプリケーション情報も参照できますが、それらの
コマンドは「vmc -h」で確認してください。
アプリケーションでMySQL/Redis/MongoDBの永続化の仕組みを利用するにはサービスを作成し、
アプリケーションへバインドします。
バインドされたサービス情報(サービス自体の情報やCredential(ホスト/ユーザー名/パスワードなど))
はENVの中のVCAP_SERVICESという変数に格納される仕組みのようです。
ですのでDBへの接続情報はENVをJSONとしてパースしVCAP_SERVICESのcredentialsから取得
する形となるものと思います。
Cloud Foundryを触ってみる。(vmc導入)
VMware社が2011/4/12に発表したPaaS環境、Cloud Foundry。
invitation の登録をしていたものの放ったらかしていたら4月末に準備OKのメールが来ていた
ので今更ながら触ってみます。
PaaSをオープンソースのCloud Foundryで仕掛けるVMwareの狙いはどこにある? - Publickey
メールによると「VMC(VMware Cloud CLI)を入れてちょ」ということなので、
下記URLを参考に入れてみます。
(とはいえgemコマンド一発でインストールできるみたいですけども。)
http://support.cloudfoundry.com/entries/20012337-getting-started-guide-command-line-vmc-users
$ gem install vmc
$ vmc -v
vmc 0.3.10
※ vmcインストールにおいて gem install としているのは、RVMを利用しているためです。(以下URL参照)
https://rvm.beginrescueend.com/rubies/rubygems/
なお、vmc導入に伴い以下の依存するgemもインストールされる模様。
highline (1.6.1) json_pure (1.5.1) mime-types (1.16) rest-client (1.6.1) rubyzip2 (2.0.1) terminal-table (1.4.2) vmc (0.3.10)
Cloud Foundryへの操作はこのvmcというコマンドライン・インターフェースで行うという
ことだと思います。
で、ガイドの文書はvmcでターゲットの変更とログインをしてみぃやとおっしゃっているので
おおせのままに。
$ vmc target api.cloudfoundry.com $ vmc login Eメールアドレス --passwd メール記載のパスワード Successfully logged into [http://api.cloudfoundry.com]
お、ログインでけた。
ログアウトは「vmc logout」により行います。
なお、早いうちに「vmc passwd」でパスワードは変更しておいた方がよいでしょう。
さて、vmcから参照できるシステム情報等を見てみましょう。
$ vmc info VMware's Cloud Application Platform For support visit support@cloudfoundry.com Target: http://api.cloudfoundry.com (v0.999) Client: v0.3.10 User: Eメールアドレス Usage: Memory (0B of 2.0G total) Services (0 of 16 total) Apps (0 of 20 total)
$ vmc runtimes +--------+-------------+-----------+ | Name | Description | Version | +--------+-------------+-----------+ | ruby18 | Ruby 1.8 | 1.8.7 | | ruby19 | Ruby 1.9 | 1.9.2p180 | | node | Node.js | 0.4.5 | | java | Java 6 | 1.6 | +--------+-------------+-----------+ $ vmc frameworks +---------+ | Name | +---------+ | grails | | node | | rails3 | | spring | | sinatra | +---------+ $ vmc services ============== System Services ============== +---------+---------+-------------------------------+ | Service | Version | Description | +---------+---------+-------------------------------+ | mongodb | 1.8 | MongoDB NoSQL store | | redis | 2.2 | Redis key-value store service | | mysql | 5.1 | MySQL database service | +---------+---------+-------------------------------+ =========== Provisioned Services ============
Node.jsやRails3をサポートしているというのが今時感ありますね。
この他のvmcの利用方法は「vmc --help」にて確認してください。
プロジェクトのデプロイは後日行ってみます。
rvmをインストール
https://rvm.beginrescueend.com/を
インストールしてみましたので、作業メモ程度に。
例のごとくUbuntu 11.04の仮想マシンを新規作成、アップデート・マネージャでパッケージの
アップデート適用した状態からのスタート。
まず、RVMインストール時に必要となるパッケージをインストールします。
$ sudo apt-get install curl git-core
そしてRVM本体をインストール
$ bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)
.bash_profileが生成されているので、sourceコマンドで反映します。
$ source .bash_profile
RVMのインストールこれにて完了。
RVMインストールの詳細はhttps://rvm.beginrescueend.com/rvm/install/を
ご覧ください。
rvmにRuby 1.9.2をインストール
まず、Ruby環境のインストールに必要なパッケージ類を「rvm notes」コマンドで確認できるようですので
コマンド実行により表示されたパッケージでシステムに足りてないものをインストール。
$ sudo apt-get install bison openssl libreadline6 libreadline6-dev zlib1g zlib1g-dev libssl-dev libyaml-dev libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev
次に、インストール可能なRubyを確認します。
コマンド「rvm list known」で、インストール可能なRubyの全リストが表示されるとのこと。
http://beginrescueend.com/rubies/list/
$ rvm list known # MRI Rubies [ruby-]1.8.6[-p420] [ruby-]1.8.6-head [ruby-]1.8.7[-p334] [ruby-]1.8.7-head [ruby-]1.9.1-p378 [ruby-]1.9.1[-p431] [ruby-]1.9.1-head [ruby-]1.9.2[-p180] [ruby-]1.9.2-head ruby-head # GoRuby goruby # JRuby jruby-1.2.0 jruby-1.3.1 jruby-1.4.0 jruby-1.6.0 jruby[-1.6.1] jruby-head # Rubinius rbx-1.0.1 rbx-1.1.0 rbx-1.1.1 rbx-1.2.0 rbx-1.2.1 rbx-1.2.2 rbx-1.2.3 rbx[-head] # Ruby Enterprise Edition ree-1.8.6 ree[-1.8.7][-2011.03] ree-1.8.6-head ree-1.8.7-head # Kiji kiji # MagLev maglev[-25716] maglev-head # Mac OS X Snow Leopard Only macruby[-0.10] macruby-nightly macruby-head # IronRuby -- Not implemented yet. ironruby-0.9.3 ironruby-1.0-rc2 ironruby-head
ほう。
最後に、Ruby 1.9.2をインストールします。
http://beginrescueend.com/rubies/installing/
rvm install ruby-1.9.2
...しばし待つ。
......インストールオワタ。
$ rvm list rvm rubies ruby-1.9.2-p180 [ i386 ]
動くのかな?
$ ruby -v プログラム 'ruby' はまだインストールされていません。 次のように入力することでインストールできます: sudo apt-get install ruby
ひょ?
公式ページに何かある・・・かな。
ん、「Setting the default Ruby」っちゅーページがありますな。
http://beginrescueend.com/rubies/default/
$ rvm --default use 1.9.2 $ ruby -v ruby 1.9.2p180 (2011-02-18 revision 30909) [i686-linux]
動いた。おk。
rvmを導入すると、$HOME/.rvm ディレクトリにRuby環境が展開されるようですね。
1.8系と1.9系を混在させなきゃいけない、といった場合などに便利でしょうねー。