Rails 4.2.3 での話。
Rails の model は、データベースとひもづくようになっているのだけど
データベースとひもづかない model を作りたいときもある。
Googleで調べてみたら、なんかいろいろコードを書いて実装したりとか、そういう機能だけを提供するgem を見かけたりもしたのだけど
本家本元の RailsGuides にちゃんと書いてありました。
ActiveModel Basics 1.7 Model
ここによると、ActiveModel::Model を include すれば、そのクラスは、validation とか使えるし、
View で form_for で利用することもできると書いてあります。
確認のため、試してみた。
$ rails new model_without_db
$ cd modle_without_db
$ bin/rails c
irb(main):001:0> class FooDb < ActiveRecord::Base
irb(main):002:1> end
=> nil
irb(main):003:0> FooDb
=> FooDb (call 'FooDb.connection' to establish a connection)
irb(main):004:0> FooDb.new
ActiveRecord::StatementInvalid: Could not find table 'foo_dbs'
... (以下略)
そうなのだ。ActiveRecord::Base を継承する場合は、ちゃんとテーブル(DB)がないとインスタンスすら作れない。
では、いよいよ、ActiveModel::Model を試してみよう。
irb(main):007:0> class FooWithoutDb
irb(main):008:1> include ActiveModel::Model
irb(main):009:1> end
=> FooWithoutDb
irb(main):010:0> FooWithoutDb
=> FooWithoutDb
irb(main):011:0> FooWithoutDb.new
=> #<FooWithoutDb:0x007f64080fbdb0>
irb(main):012:0>
おおっ。インスタンスができてる。ってこれだけじゃ意味ねーじゃん。ということで、validation も使えるか試してみる。
irb(main):012:0> class FooWithoutDb
irb(main):013:1> attr_accessor :foo
irb(main):014:1> validates :foo, presence:true
irb(main):015:1> end
=> {:presence=>true}
irb(main):016:0> foo = FooWithoutDb.new
=> #<FooWithoutDb:0x007f64080976d0>
irb(main):017:0> foo.valid?
=> false
irb(main):018:0> foo.foo = 'hogehoge'
=> "hogehoge"
irb(main):019:0> foo.valid?
=> true
おおっ。ちゃんと validation も使えそう。
このあと、もうちょっと試してみたけど、実際に app/model 配下に、ActiveModel::Model をinclude したクラスのファイルを作って
View とちょっとだけ連携してみたら、それっぽく動作してくれた。
Rails も便利になったものです。(機能が増えすぎて複雑怪奇になっているとも...)
FooWithoutDb.build や FooWithoutDb.create は使えないので、RSpecとかでテスト書くときには、注意した方がいいかも。
ちなみに、ActiveModel Basics は、'Work in progress' (2015-08-15現在)なので
まだまだ新しい情報が追加されるかも知れません。
残念ながら、日本語翻訳ページの Active Model の基礎 には、この説明がまだありません(2015-08-15現在)。
最近のコメント