Archive for category Ruby on Rails

ActiveRecord::Base#find(_by_id)? のお話

最近Ruby on Railsばかりなので、今回もRailsのお話。

何も考えずに特定のIDのレコードを見つける際は、「ActiveRecord::Base#find」という超基本メソッドを使うけれど、同時に、XXXというフィールドに対して「ActiveRecord::Base#find_by_XXX」なるメソッドも定義されているので、「ActiveRecord::Base#find_by_id」でも同じようにidに紐付けて見つけ出せる。

以上は当たり前の話だが、この同じような2つ、重要なところが違う。すなわち、そのIDに紐付くレコードが存在しない場合。

ActiveRecord::Base#find」は例外が生じる。

1
2
3
4
5
6
7
Post.find(1)
#=> ActiveRecord::RecordNotFound: Couldn't find Post with ID=1
#	from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:1586:in `find_one'
#	from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:1569:in `find_from_ids'
#	from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:616:in `find'
#	from (irb):6
#	from :0

ActiveRecord::Base#find_by_id」は nil を返す。

1
2
Post.find_by_id(1)
#=> nil

このお話はそれなりに有名なようですが、find_by_idを使えば、例えばこういうコードが書けて気分がいいですね。

Read the rest of this entry »

 

Railsのdb:migrateは、最新バージョンより古くてもさかのぼる

どういうことかと言うと、

rails(1) でつくる。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[udzura@udzra.jp rails]$ rails -v
Rails 2.3.5
[udzura@udzra.jp rails]$ rails -d mysql migtest
      create
      create  app/controllers
      create  app/helpers
      create  app/models
      create  app/views/layouts
      create  config/environments
...
      create  log/server.log
      create  log/production.log
      create  log/development.log
      create  log/test.log

マイグレーションを作る。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[udzura@udzra.jp rails]$ cd migtest/
[udzura@udzra.jp migtest]$ script/generate model User name:string
      exists  app/models/
      exists  test/unit/
      exists  test/fixtures/
      create  app/models/user.rb
      create  test/unit/user_test.rb
      create  test/fixtures/users.yml
      create  db/migrate
      create  db/migrate/20100122041512_create_users.rb
[udzura@udzra.jp migtest]$ script/generate model Blog user_id:integer entry:text
      exists  app/models/
      exists  test/unit/
      exists  test/fixtures/
      create  app/models/blog.rb
      create  test/unit/blog_test.rb
      create  test/fixtures/blogs.yml
      exists  db/migrate
      create  db/migrate/20100122041555_create_blogs.rb

2099年とかすっごい未来にリネームする。

1
2
3
4
5
6
[udzura@udzra.jp migtest]$ ls -l db/migrate/
合計 8
-rw-rw-r--  1 udzura udzura 193  122 13:15 20100122041512_create_users.rb
-rw-rw-r--  1 udzura udzura 217  122 13:15 20100122041555_create_blogs.rb
[udzura@udzra.jp migtest]$ mv db/migrate/20100122041555_create_blogs.rb \
  db/migrate/20990122041555_create_blogs.rb

マイグレートする。

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
[udzura@udzra.jp migtest]$ rake db:create
(in /var/web-devel/rails/migtest)
[udzura@udzra.jp migtest]$ rake db:migrate
(in /var/web-devel/rails/migtest)
==  CreateUsers: migrating ====================================================
-- create_table(:users)
   -> 0.0038s
==  CreateUsers: migrated (0.0041s) ===========================================
 
==  CreateBlogs: migrating ====================================================
-- create_table(:blogs)
   -> 0.0032s
==  CreateBlogs: migrated (0.0035s) ===========================================
 
[udzura@udzra.jp migtest]$ mysql -uroot -pxxxx -e "SHOW TABLES" migtest_development
+-------------------------------+
| Tables_in_migtest_development |
+-------------------------------+
| blogs                         |
| schema_migrations             |
| users                         |
+-------------------------------+
[udzura@udzra.jp migtest]$ rake db:version
(in /var/web-devel/rails/migtest)
Current version: 20990122041555

マイグレーションを加える。当然、さっき作った二つのマイグレーションの間に入ります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[udzura@udzra.jp migtest]$ script/generate model UserFriend user_id:integer friend_user_id:integer
      exists  app/models/
      exists  test/unit/
      exists  test/fixtures/
      create  app/models/user_friend.rb
      create  test/unit/user_friend_test.rb
      create  test/fixtures/user_friends.yml
      exists  db/migrate
      create  db/migrate/20100122041954_create_user_friends.rb
[udzura@udzra.jp migtest]$ ls -l db/migrate/
合計 12
-rw-rw-r--  1 udzura udzura 193  122 13:15 20100122041512_create_users.rb
-rw-rw-r--  1 udzura udzura 249  122 13:19 20100122041954_create_user_friends.rb
-rw-rw-r--  1 udzura udzura 217  122 13:15 20990122041555_create_blogs.rb

こういう場合でもさかのぼってマイグレーションを実行してくれます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[udzura@udzra.jp migtest]$ rake db:migrate
(in /var/web-devel/rails/migtest)
==  CreateUserFriends: migrating ==============================================
-- create_table(:user_friends)
   -> 0.0067s
==  CreateUserFriends: migrated (0.0071s) =====================================
 
[udzura@udzra.jp migtest]$ mysql -uroot -pxxxx -e "SHOW TABLES" migtest_development
+-------------------------------+
| Tables_in_migtest_development |
+-------------------------------+
| blogs                         |
| schema_migrations             |
| user_friends                  |
| users                         |
+-------------------------------+

何が嬉しいの?

例えば、実表のマイグレーションを通常の作成時の日次で、ビュー表を作成するマイグレーションを「2099年」の日次で、という風にしておくと、「必ずすべての実表が作られてからビュー表が定義される」ことが保障され、なおかつ、ビュー表の定義を変更した際、作り直しが rake(1) で容易にできます。

ポイントは rake db:migrate:down VERSION=2099XXXXXXXXXX

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[udzura@udzra.jp migtest]$ rake db:migrate:down VERSION=20990122041555
(in /var/web-devel/rails/migtest)
==  CreateViewBlogs: reverting ====================================================
-- drop_table(:view_blogs)
   -> 0.0277s
==  CreateViewBlogs: reverted (0.0280s) ===========================================
 
[udzura@udzra.jp migtest]$ rake db:migrate
(in /var/web-devel/rails/migtest)
==  CreateViewBlogs: migrating ====================================================
-- create_table(:view_blogs)
   -> 0.0472s
==  CreateViewBlogs: migrated (0.0475s) ===========================================
 
[udzura@udzra.jp migtest]$

RailsでCreate Viewしたい際は、普通に execute しないといけません。なので、そもそも「RailsでView表使うとかあほか」って方もいると思う。引き出しの一つとして。

 

Gitorious入れたメモ

日ごろgithubさんにお世話になっておりますが、Gitoriousというサービスは自分のコードを公開し、個人でインストールできるようなので入れてみたメモ。

概要

ホストするOSはUbuntu 9.10。

手順は、9.04の場合のものが公式Wikiにあったりする(http://gitorious.org/gitorious/pages/UbuntuInstallation)のでそれを大幅に参照した。基本的にコレの通りで問題ないのだが、Gitorious自体のバージョンが上がったこともあって微妙に違う点もある。

以下、日本語Remix CDを入れたてのまっさらな状態からの構築を想定。

Read the rest of this entry »

 

RailsでExcelをダウンロードさせる

色々試してて、多少は形になったのでメモしときます。

まず、RubyでExcelを作らないといけません。色々方法はありますが、というか素直な方法はJRuby+POIなんじゃないかとも思いますが、今回は「spreadsheet」を使います。

spreadsheet ライブラリとは

spreadsheetは普通にgemでインストールできます。

1
sudo gem install spreadsheet

spreadsheet自体には、 .to_blob に当たるインスタンスメソッドがありません(ようです)が、書き込み先にFile IOを指定できます。なので、いったんTempfileに書き込んで、 read して send_data する方法で出来るんじゃないかと思いました。

emvironment.rbで require 'spreadsheet' すると、一緒にtempfile.rbも読み込まれる模様です。

Read the rest of this entry »

 

Railsでブログパーツ

gist.githubは、右上の「embed」をクリックすると、

のようなコード片が出てきて、それをブログ等に貼り付けるとシンタクスハイライトされたコードが載せられる。

こんな感じのブログパーツをRuby on Railsで作るとどうなるかなーとか考えた。
Read the rest of this entry »