Archive for category Ruby on Rails

Ruby+heroku.comを利用して、コストと手間をなるべくかけずにサイトを作る: draft

目標

小規模サイト(中小企業のコーポレートサイトを想定)をほとんどタダみたいなコストで、なるべく手間をかけずに作れないか?

方法論

前提

Rubyを使いたい。

ホスティング

heroku.comを利用する。

  • Pros
    • No Cost(“Blossom” Planならば)
    • Ruby使用可能
    • デプロイが楽 – git
    • 最低限のプランとはいえ、クラウドなので可用性は保証される
    • 独自ドメインも使える(「年」額で500円とかなので、ここは買ってしまうのがいいだろう)
  • Cons
    • Rubyしか使えない
    • バックエンドはほとんど手をかけられない
    • “Blossom”で使えるDB容量はわずか「5MB」
      • 月15ドルで20GBにアップグレードできるけど、その額を払うならVPSを使いたくなる。。
    • レイテンシは時々気になる程度

CMS

Ruby on Rails製の二つのアプリケーションが選択肢になる。

  • Radiant CMS
    • 多機能CMS
    • 割とカスタマイズできる
    • 日本語化はそこそこ(それも、0.9.0限定)
    • CMSで使うタグの追加程度なら楽にできそう
    • エクステンション豊富
    • 0.9.0はまだ安定感にかける(特にエクステンションの対応状況)

まとめ

5MBの制約があるので、あまりに大規模だったりあまりに画像を使用するサイトは無理だと思う。でも、普通にコーポレートサイトなら出来るんじゃない? って思ったりもする。5MBつっても素材とかは入らないわけだから。。

GAEとかの方が楽だったりするんかいなー。。。とも思うけど。RadiantやTypoはある程度ハックする前提で。

次回からは、実際に構築してみる。と言うか、その前にTypoを試したりRadiantを試した感想とかを書く。

 

emacs23始めました on Ubuntu 9.10

標記のとおり。遅まきながら,ですが。

普段,NetBeansのRailsモードで開発してたんですが,Rinariなる凄く便利なelispができたようなので,試すついでに色々設定してみました。emacsは23.1.1です。パッケージで言うとemacs23、と明示的に指定します。単純に23のほうが日本語フォントの設定がしやすいからです。。

インストールと設定

一部,emacsとRinariで快適Rails開発! と言う素晴らしい記事を激しくコピペしつつ,以下の手順です。

Read the rest of this entry »

 

またRails: たくさんincludeしてるときの検索

以下のようなモデルがあります(適当に考えたんですが、SNS的な何かを想定してみましょう)。

1
2
3
4
5
6
7
8
9
10
11
12
class Post < ActiveRecord::Base
  belongs_to :member
end
 
class Member < ActiveRecord::Base
  belongs_to :job
  has_many :posts
end
 
class Job < ActiveRecord::Base
  has_many :members
end

「日付が2010年2月6日で、かつ書いた人の職業名が”Engineer”の人の日記一覧を抽出したい」んですけど、どうしましょう。なお、date属性はPostクラスに、job_name属性はJobクラスにくっついています。

なので、以下では全然ダメです。

1
2
3
4
5
6
Post.find(:all,
  :conditions => {
    :date => Date.new(2010, 2, 6),
    :job_name => "Engineer"
  },
  :include => {:member => :job})

SQL (0.2ms) SET NAMES 'utf8'
SQL (0.6ms) SET SQL_AUTO_IS_NULL=0
Post Load (0.0ms) Mysql::Error: Unknown column 'posts.job_name' in 'where clause': SELECT * FROM `posts` WHERE (`posts`.`date` = '2010-01-31' AND `posts`.`job_name` = 'Engineer')

Read the rest of this entry »

 

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表使うとかあほか」って方もいると思う。引き出しの一つとして。