スポンサーリンク

Ruby on RailsのModel内に記述するメソッドの分類表

Ruby on Railsで,子モデルクラスに記述すべきメソッドの,分類済み一覧表。


「子モデル」とは,

  • DBにアクセスするクラス。
  • そのクラスのインスタンスオブジェクトがアプリ全体で持ち回され,単一のレコードを扱う上で便利な働きをする。


これに対し,「親モデル」(=サービス層)は,

  • 業務や機能のビジネスロジックなど,コントローラの各アクションから呼び出されるひとまとまりの処理をトランザクション付きで記述するクラス。
  • 業務処理を記述するために,各種の子モデルクラスのインスタンスを生成して参照や保存などを行なわせる。ちょうど,子モデルから見れば「マネージャ」の役割をする。コントローラから見れば,機能に関する「サービス」である。

以下は,

  • (1)子モデルのメソッド分類
  • (2)メソッドの書き分け規約

(1)子モデルのメソッド分類表



子モデル内の実装メソッドの分類

CRUDの
発生する
レイヤ→

メモリ上

DB上

レシーバ分類→



↓CRUD分類

インスタンス
メソッド

インスタンス
メソッド

クラス
メソッド

C (Create)

new (コンストラクタ)

save

create

R (Read)

getterメソッド類

reload

find

各種動的ファインダ

U (Update)

setterメソッド類

update

update_attributes


find + setter + save

find + update


D (Delete)

- (デストラクタ)

destroy


delete

destroy


delete_all

destroy_all


グレーアウトされた部分は非推奨

6. クラス、モジュール
http://www.ruby-lang.org/ja/man/html/...
レシーバがクラス名であればクラスメソッドになる


http://blade.nagaokaut.ac.jp/cgi-bin/...
Rubyには明示的なオブジェクト破棄の方法は無い


ActiveRecord reload(options = nil)
http://ar.rubyonrails.org/classes/Act...


ActiveRecord 更新系
http://d.hatena.ne.jp/elm200/20070318...

  • deleteとdestroyの違い


操作の対象が

  • 「メモリ上」か(=永続化を伴わない一時的な操作か),
  • あるいは「DB上」か(=永続化を伴う最終確定的な操作か),

という観点で考えると,どんなモデルメソッドであってもすっきり分類できる。


本来,「CRUD」は永続化レイヤに用いる用語であって,「メモリ上でCRUD」するなどと言ったりはしない。

だが,便宜上CRUDに対応付けると,やはりすっきり分類できる。



「ORM(object-Relational Mapping)フレームワークを使っている場合は,メモリ上でのレコードオブジェクトの生成消滅も,一種のCRUDと呼ぶ事にしよう。」という事である。



例えば,「読み取り」を行なうメソッドは,以下の2種類あると言える。

  • (処理真っ最中の,APサーバのメモリ上に,「論理的に」存在する)オブジェクトに対して状態を問い合わせるメソッド。
    • 狭義のgetterや,
    • 広義のgetter(単にオブジェクトのフィールドを取得するだけでなく,何らかの演算を伴って,そのオブジェクトに関する有用な情報を引き出すメソッド)。
  • (確定済みの,DBサーバのファイルシステム上に「物理的に*1」存在する)DBのレコードに対して状態を問い合わせるメソッド。
    • 純粋な意味での「参照系のメソッド」。
    • ファインダ,検索。


※上の表には,この2つに加えてreloadも記載してある。このメソッドは永続化レイヤへのアクセスを伴う。


(2)メソッドの書き分け規約

これら,モデル内に記述するメソッドの書き分け(棲み分け)方。

  • publicとprivateでは,
    • publicを先に書く。(公開APIなので)
    • publicのコード量を可能な限り減らす。(インタフェースと実装を切り離す)
  • インスタンスメソッドとクラスメソッドでは,
    • クラスメソッドを先に書く。(一般的なコーディング規約)
    • クラスメソッドを避け,インスタンスメソッドを可能な限り充実させる。(オブジェクト指向はインスタンス中心のプログラミングスタイル)
  • 操作対象のレコード数について
    • 単一レコードを扱う処理を,子モデル内に記述する。
    • 複数レコード/複数テーブルを扱う処理や,トランザクションが必要になる処理は,子モデルに記述しない。親モデルに記述する。

ソースコードでのクラスの記述順序(C++)
http://d.hatena.ne.jp/c299792458/2010...

  • publicなAPIを先に書く。そうすれば変更されやすい要素を後ろのほうに押しやることができる。


メソッド (計算機科学)
http://ja.wikipedia.org/wiki/%E3%83%A...
インスタンスメソッド (instance method) とはインスタンスに属するメソッドのことであり、生成されたインスタンスからアクセスする。インスタンスメソッドはオブジェクト指向プログラミングの中核をなし、もっともよく使われる。


Rubyコーディング規約
http://shugo.net/ruby-codeconv/codeco...
メソッドの記述順序


Ruby on Railsの「えせMVC」の弊害
http://satoshi.blogs.com/life/2009/10...
RailsのActiveRecord利用時には,DBアクセス層(子モデル)の上にビジネスロジック層(親モデル)を設けよ


リストにすると,下記のようになる。

  • public(減らす)
    • classメソッド(減らす)
      • DB操作
        • C
        • R(※ここだけはどうしても検索系のメソッドが増える)
        • U
        • D
    • instanceメソッド(増やす)
      • メモリ上操作
        • C
        • R(広義のアクセサ)
        • U
        • D
      • DB操作
        • C
        • R
        • U
        • D
  • private(増やす)
    • publicと同じ

注:

  • privateなクラスメソッドは, private_class_method で定義。
  • privateなインスタンスメソッドは, private で定義。

Rubyでクラスメソッドをprivateにする正しい方法
http://blog.s21g.com/articles/561

  • ただし,特異メソッドを使う方が一般的




 

*1:物理的とは言っても,最近はオンメモリDBなどもあるのだが・・・