Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

あなたのコードはどこに行きますか?

Railsチュートリアルを終了して独自のアプリを起動すると、混乱が生じます。非CRUDの一般的なロジックはどこに行くのですか? Twitterからフォロワーを獲得することはMVCにどのように適合しますか? 2人に聞いてみると、4つの答えが得られます。または、あなたが机に頭をぶつけている間、あなたのスレッドは何時間もお互いを侮辱する賢い人々の束に発展します。いずれにせよ、あなたは頭痛の種になります。

夢見ていたアプリを作成するには、いくつかが必要です。 一般的な、Rails以外のロジック。 では、コードをどこに配置し、それでも物事をシンプルに保つのでしょうか?

簡単に始められる場所

既存のActiveRecordモデルに関連していると感じるロジックがある場合は、まずそのモデルに配置します。 たとえば、ゲームがある場合 モデルであり、CSVファイルから多数のゲームをインポートしたかったので、そのメソッドを Gameに直接配置しました。 クラス:

app / models / game.rb
class Game < ActiveRecord::Base
  def self.parse_from_csv(csv_string)
    games = []
    CSV.parse(csv_string, quote_char: "'") do |row|
      games << Game.from_csv_row(row) if (row[0] == 'G')
    end
    games
  end

  def self.from_csv_row(row)
    Game.new({
      dgs_game_id: row[1],
      opponent_name: row[2],
      created_at: row[4],
      updated_at: row[4],
    })
  end
end

メソッドに必要なすべての情報が手元にあります。簡単にテストできます。そして、おそらく新しい寄稿者が最初にそのロジックを探す場所です。

ただし、そのモデルを追加および変更し続けると、大きく複雑になります。モデルのさまざまな部分が奇妙な方法で相互作用します。 変更すればするほど、変更が難しくなります。

その場合、おそらくそのコードを非ActiveRecordモデルにリファクタリングすることをお勧めします。

非ActiveRecordモデル

Railsアプリにあるからといって、アクティブ/アクションから継承する必要があるという意味ではありません。

プレーンなRubyオブジェクトで独自のRubyコードを記述し、それらをRailsアプリで使用できます。 これらのオブジェクトは、問題の一部をモデル化しているため、引き続きモデルと呼ぶことができます。データを保存するActiveRecordデータベースがないだけです。

次回そのゲームのCSVパーサーに取り組んだときは、 Game クラスが少し大きくなりすぎていました。そこで、パーサーロジックを独自の GameCSVParserに移動しました クラス。

コミット全体はここにありますが、これは非ActiveRecordクラスがどのように見えるかです:

app / models / game_csv_parser.rb
class GameCSVParser

  def initialize(csv_string)
    @rows = CSV.parse(csv_string, quote_char: "'")
  end

  def games
    game_rows.map { |row| Game.new(game_attributes(row)) }
  end

  private

  def game_rows
    @rows.select { |row| is_game_row?(row) }
  end

  def game_attributes(row)
    {
      dgs_game_id: row[1],
      opponent_name: row[2],
      created_at: row[4],
      updated_at: row[4],
    }
  end

  def is_game_row?(row)
    row[0] == 'G'
  end
end

追加するロジックが特定のActiveRecordモデルに関連していると思われない場合は、新しいプレーンなRubyオブジェクトの作成に進みます。または、コードがアプリにまだ存在していないものの一部であると思われる場合。それ以外の場合は、ほとんどの場合、リファクタリングによってポップアップします。

プレーンなRubyオブジェクトを使用すると、何でも書くことができます。しかし、あなたが何でも書くことができることを知っている 方向性については役に立ちません。どのような方法が必要ですか?すべての新しいオブジェクトはどのように相互作用しますか?

多くのRailsアプリは同じカテゴリを使用します プレーンなRubyオブジェクトの。 これらのカテゴリは、他の開発者が認識できるコードを作成するために従うことができるパターンです。すでにいくつか聞いたことがあるかもしれません。

サービスオブジェクト、プレゼンター、およびジョブ

サービスオブジェクト、プレゼンター、およびジョブについて特別なことは何もありません。これらは、特定の認識可能な方法で動作する単なるRubyオブジェクトです。

たとえば、Resqueジョブperformを持つプレーンなRubyクラスです メソッドと@queue

app / workers / fetch_games_for_player.rb
class FetchGamesForPlayer
  @queue = :default

  def self.perform(player_id)
    player = Player.scoped_by_id(player_id).ready_for_fetching.first
    player && player.fetch_new_games!
  end
end

実行 ジョブの実行時に呼び出されます。

プレゼンター ビュー内でのみ意味のあるコードを持つプレーンなRubyオブジェクトです:

app / presenters / user_presenter.rb
class UserPresenter
  def show_related_users?
    @user.related.count > 3
  end
end

また、Railsのビューヘルパーが含まれている場合や、いくつかの異なるオブジェクトを取得して、ビューの利便性のためにそれらを1つの統合オブジェクトとして扱う場合もあります。

サービスオブジェクト 実行するプロセスを表すプレーンなRubyオブジェクトです。たとえば、投稿にコメントを書くと、次のようになります。

  1. コメントを残してください。
  2. 投稿の作成者に通知メールを送信します。

サービスオブジェクトは両方を実行し、そのロジックをコントローラーから遠ざけることができます。

ここでは、サービスオブジェクトについて優れた見解があります。例がたくさんあります。

単純なプロセスの場合、サービスオブジェクトを気にしません。 ただし、コントローラーが重くなり始めた場合は、追加のロジックを配置するのに適した場所です。

これらのパターンを使用して、独自のビジネスロジックを整理できます。これらは単なるRubyオブジェクトですが、特定のフレーバーを共有し、名前があり、他の開発者と話し合うことができるRubyオブジェクトです。

どこから始めますか?

Rails以外のビジネスロジックが進む可能性のある場所はたくさんあります。選ぶのは難しいかもしれません。これが私がすることです:

  1. ロジックが既存のクラスにほとんど関連している場合、それがActiveRecordモデルであっても、私はそれをそのクラスに入れます。
  2. 既存のクラスに適合しない場合は、ロジックを保持するための新しいプレーンRubyクラスを作成します。
  3. ロジックがまだ存在していないものの一部であると思われる場合は、そのための新しいプレーンなRubyクラスを作成します。
  4. 後でコードに戻ってモデルが複雑になりすぎたり、そのモデルでコードが意味をなさなくなったりした場合は、コードを独自のプレーンなRubyクラスにリファクタリングします。
  5. コードがビューでのみ意味をなす場合は、ヘルパーに追加するか、プレゼンターを作成します。
  6. コードをHTTPリクエスト中に実行する必要がない場合、またはバックグラウンドで実行する必要がある場合、コードはジョブに含まれます。
  7. プロセスのいくつかの異なるモデルまたはステージを調整していて、コントローラーが理解しにくい場合は、それをサービスオブジェクトに入れます。

君はどうでしょう?あなたのコードはどこに行きますか?そして、これら以外に役立つと思ったパターンはありますか? コメントを残して私に知らせてください。

まだプロセスがない場合は、私のものを試してください。それがあなたにどのように合うかを見てください。コードを書くための完璧な方法はありませんが、行き詰まったときは、このようなプロセスを開始するのに役立ちます。


  1. 基本的なOOP原則を使用してRubyコードを劇的に改善する方法

    最も重要なオブジェクト指向の原則の2つは、凝集度と結合度です。 結束 クラス内のすべてのメソッド間の関係についてです。それらは同じインスタンス変数とパラメータのセットを使用しており、すべてが同じ目標に向かって協力しています ?それとも、すべての方法が互いに分離していると感じますか? カップリング クラスが他のクラスにどの程度依存しているか、システムの他の部分にどの程度「結びついている」か、そしてこのクラスを単独で使用できるかどうかです。 これらの概念は両方とも、特定のレンズのセットを通してコードベースのすべてのクラスを確認するのに役立ちます。これらのレンズは、クラスのデザインがどれ

  2. MRIソースコードの調査

    しばらくRubyを使用している場合は、内部でいくつかのものがどのように機能するかについて興味があるかもしれません。 Rubyの内部を深く掘り下げる1つの方法は、Rubyを機能させるソースコードを読み取ることです。 Cを知らなくても、面白いものをいくつか拾うことができます。 ソースコードは、Rubyのgithubリポジトリにあります。 理想的には、クラス名とメソッド名を簡単に見つけることができるCodequeryのようなツールを使用する必要があります。 コアクラスの調査 ほとんどの探索はルートフォルダで行われます。ここに、Objectなどのすべてのコアクラスのソースコードがあります。 o