245

私は Rails をとても楽しんでおり (私は基本的に RESTless ですが)、Ruby が非常に OO であることを楽しんでいます。それでも、巨大な ActiveRecord サブクラスと巨大なコントローラを作成する傾向は非常に自然です (たとえリソースごとにコントローラを使用したとしても)。より深いオブジェクトの世界を作成する場合、クラス (およびモジュール) をどこに配置しますか? ビュー(ヘルパー自体?)、コントローラー、モデルについて質問しています。

Lib は大丈夫です。開発環境でリロードするための解決策をいくつか見つけましたが、これを行うためのより良い方法があるかどうか知りたいです。クラスが大きくなりすぎることを本当に心配しています。また、エンジンについてはどうですか?どのように適合しますか?

4

4 に答える 4

62

更新: Rails 4 の新しいデフォルトとして、 Concerns の使用が確認されました。

モジュール自体の性質に大きく依存します。私は通常、コントローラー/モデル拡張機能をアプリ内の /concerns フォルダーに配置します。

# concerns/authentication.rb
module Authentication
  ...
end    

# controllers/application_controller.rb
class ApplicationController
  include Authentication
end



# concerns/configurable.rb
module Configurable
  ...
end    

class Model 
  include Indexable
end 

# controllers/foo_controller.rb
class FooController < ApplicationController
  include Indexable
end

# controllers/bar_controller.rb
class BarController < ApplicationController
  include Indexable
end

/lib は、汎用ライブラリとして私が好む選択肢です。私は常に、すべてのアプリケーション固有のライブラリを配置する lib にプロジェクトの名前空間を持っています。

/lib/myapp.rb
module MyApp
  VERSION = ...
end

/lib/myapp/CacheKey.rb
/lib/myapp/somecustomlib.rb

Ruby/Rails のコア拡張は通常、構成初期化子で行われるため、ライブラリは Rails ブーストラップで一度だけロードされます。

/config/initializer/config.rb
/config/initializer/core_ext/string.rb
/config/initializer/core_ext/array.rb

再利用可能なコード フラグメントの場合、他のプロジェクトで再利用できるように (マイクロ) プラグインを作成することがよくあります。

ヘルパー ファイルは通常、ヘルパー メソッドを保持し、オブジェクトがヘルパー (フォーム ビルダーなど) によって使用されることを意図している場合はクラスを保持することもあります。

これは本当に一般的な概要です。よりカスタマイズされた提案が必要な場合は、具体的な例について詳細を提供してください。:)

于 2009-07-01T12:15:30.680 に答える
10

...巨大なActiveRecordサブクラスと巨大なコントローラーを作成する傾向は非常に自然です...

「巨大」は気になる言葉です...;-)

あなたのコントローラーはどのように巨大になっていますか?それはあなたが見なければならないことです:理想的には、コントローラーは薄いはずです。経験則を選んで、コントローラーメソッド(アクション)ごとに5行または6行を超えるコードを定期的に使用している場合は、コントローラーが太すぎる可能性があります。ヘルパー関数またはフィルターに移動する可能性のある重複はありますか?モデルにプッシュダウンできるビジネスロジックはありますか?

モデルはどのようにして巨大になりますか?各クラスの責任の数を減らす方法を検討する必要がありますか?ミックスインに抽出できる一般的な動作はありますか?または、ヘルパークラスに委任できる機能の領域はありますか?

編集:少し拡張しようとしていますが、うまくいけば、何かをひどく歪ませないでください...

ヘルパー:住んでいapp/helpersて、主にビューを単純にするために使用されます。これらは、コントローラー固有(そのコントローラーのすべてのビューでも使用可能)または一般的に使用可能(module ApplicationHelperapplication_helper.rbで)のいずれかです。

フィルタ:いくつかのアクションで同じコード行があるとします(かなり頻繁に、params[:id]または同様のを使用してオブジェクトを取得します)。その複製は、最初に別のメソッドに抽象化され、次に、などのクラス定義でフィルターを宣言することにより、アクションから完全に抽象化できますbefore_filter :get_objectActionControllerRailsガイドのセクション6を参照してください。宣言型プログラミングを友だちにしましょう。

モデルのリファクタリングは、もう少し宗教的なことです。ボブおじさんの弟子たちは、例えば、あなたがSOLIDの5つの戒めに従うことを提案します。Joel&Jeffは、より、より「実用的な」アプローチを推奨するかもしれませんが、その後はもう少し和解したように見えました。明確に定義された属性のサブセットを操作するクラス内の1つ以上のメソッドを見つけることは、ActiveRecordから派生したモデルからリファクタリングされる可能性のあるクラスを特定する1つの方法です。

ちなみに、RailsモデルはActiveRecord::Baseのサブクラスである必要はありません。言い換えれば、モデルはテーブルの類似物である必要はなく、格納されているものに関連している必要もありません。さらに良いことに、Railsの規則に従ってファイルに名前を付ける限りapp/models(Railsが何を検索するかを確認するには、クラス名で#underscoreを呼び出します)、Railsは何requireも必要とせずにファイルを検索します。

于 2009-07-01T14:08:24.150 に答える
2

これは、「シン コントローラー」哲学から生じると思われるファット モデルのリファクタリングに関する優れたブログ投稿です。

http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/

基本的なメッセージは「ファット モデルからミックスインを抽出しないでください」です。代わりにサービス クラスを使用してください。作成者はそのための 7 つのパターンを提供しています。

于 2015-09-15T07:58:45.877 に答える