Grails
Rails
RubyOnRails
移行応援

GrailsとRailsの比較 〜GORMとActive Recordの新規保存処理の違い〜

More than 1 year has passed since last update.

GrailsからRailsに自分が移行中なのですが、

移行応援ということで、いるかわかんないですが同じような人のためにGrailsとRailsの比較します。

Grailsは3.1.4、Railsは5.0.0beta3で試しています。

今回はGORMとActive Recordの、オブジェクトの新規保存時の比較です。

各々のフレームワーク詳しい方、もし間違いとかあれば教えて下さい。


比較


基本


Grails

save()を利用します。

def book = new Book(title: "New Book")

book.save()

ドキュメント:https://grails.github.io/grails-doc/latest/ref/Domain%20Classes/save.html


Rails

同じようにsaveがあります。

book = Book.new(title: "New Book")

book.save

オブジェクトのインスタンス作成と保存を一気に行うcreateもあります。

Grailsの方には同様のAPIはありません。

book = Book.create(title: "New Book")

ドキュメント:http://edgeguides.rubyonrails.org/active_record_basics.html#create


違い


基本的な戻り値

下記のように異なります。

フレームワーク
API
戻り値

Grails
save()
保存されたインスタンス or null

Rails
save
true or false

Rails
create
生成されたインスタンス

個人的に面白いなーと思ったのは、createがvalidationのパスする、しないにかかわらずインスタンスを生成して返すということです。(状態としてはもちろんinvalidになる)

参考:http://stackoverflow.com/questions/23975835/ruby-on-rails-active-record-return-value-when-create-fails

Grailsのsave()がバリデーションこけたときにnullを返すのはそんな好きではなかったですが(なので例外出るようにしてました。後述)正常時もインスタンス返してくるのも不思議な気分。

と思ったけど、createの場合はインスタンス返してくれないとバリデーションに引っかかったエラー情報がとれないですもんね、と納得。


保存時に例外を出したいとき

こんな風に違います。

フレームワーク
API

Grails

save(failOnError: true)を使う

Rails

save! or create!を使う

Grailsの方の failOnErrorはけっこう冗長な気がするので、Railsのこういう気配り好きです。

ただ、今は!にまだ慣れなくて、APIドキュメント読みながらだけど。

なお、どちらのフレームワークでも、グローバルな設定で例外投げるかtrue/false返すかは変更できるようです(まだRailsの方調べてない)


バリデーションをスキップしたいとき

どちらのフレームワークも、保存用のAPI内でバリデーションが走ります。ただし、それらをスキップする方法があります。

save(validate: false)を使います。

シンタックスは全く同じなんですが、スタンスは若干違っていそうで、Railsのドキュメントには

They should be used with caution.

(これらは慎重に利用されるべきだ)

という教訓的な記述がありました。


感想

さすがRailsをよく参考にしているだけあって、かなりGrailsは似ているなと感じます。

ただ、似ているだけにフィーリングで使ってしまうと、細かいところでつまづくので注意せねばと考えています。