Railsデザインパターン:プレゼンターとサービスオブジェクト
なぜデザインパターンが必要なのですか?
問題は、RailsアーキテクチャのModel-View-Controllerが、コードを配置するための基本的な構造を提供することです。
しかし、これだけでは不十分です。
情報を提示することが目標である場合、ビューは大きくなり、論理に満ちたものになります。
コントローラーは、コントローラーがその重要な作業を行うために必要なものを超えた詳細を保持しています。
解決策は何ですか?
これらの問題を解決するために、デザインパターンの形で2つのソリューションを作成しました。
- プレゼンターパターン
- サービスオブジェクトパターン
それらを正確に実装する方法について全員が同意しているわけではありませんが、私に適したバージョンを提供します。
これらのパターンを調べてみましょう!
Railsでプレゼンターを使用する方法
ビューはプレゼンテーション用です。つまり、HTML、CSS、およびERB(Embedded Ruby)です。
ActiveRecordがあってはなりません ビューでのクエリ。
そして、ほとんどのロジックは除外する必要があります ビューをできるだけクリーンで操作しやすいものにしたい場合。
「論理」とは、ifステートメントと三項演算子を使用して意思決定を行うことを意味します
今の質問は…
どのように?
ビューのロジックを処理する最初のツールは、ヘルパーを使用することです。
多くのビューで使用するグローバルフォーマット方法がある場合は、ヘルパーが最適です。
例 :
マークダウンのレンダリング、特定の形式での日付の表示、テキストからの特定の単語の削除など。
このように :
module DateHelper
def date_as_month_and_year(date)
date.strftime("%B %Y")
end
end
このコードはapp/helpersの下に保存できます フォルダとdate_helper.rb ファイル。
ヒントはこちら :
常に引数を介してヘルパーメソッドに入力を渡し、インスタンス変数に依存しないでください。
これにより、多くの問題を回避できます。
ヘルパーメソッドには制限があります 、特にビューのすべてのフォーマットのニーズにそれらを使用する場合。
彼らは構築され、あらゆる種類の組織を欠く傾向があります。
解決策が近づいています!
複雑な条件とフォーマットメソッドをプレゼンターオブジェクトに置き換える
次のようなビューがあるとします:
<p>
Post title: <%= post.title.gsub("forbidden word", "") %>
<%= link_to "Read post", post, class: "w-75 p-3 text-#{post.draft? ? "orange" : "green"} border-#{post.draft? ? "orange" : "green"}" %>
</p>
かなり短いですよね?
しかし、これらの三項演算子と重複したコードでは非常に複雑に感じます。
良くない!
これを解決するためのプレゼンタークラスを作成しましょう。
方法は次のとおりです :
class PostPresenter
def initialize(post)
@post = post
end
def title_without_forbidden_words
@post.title.gsub("forbidden word", "")
end
def css_color
@post.draft? ? "orange" : "green"
end
end
これをapp/presenters/post_presenter.rbに保存します 、presentersを作成します お持ちでない場合はフォルダ。
これで、ビューを変更できます。
このように :
<% presenter = PostPresenter.new(post) %>
<p>
Post title: <%= presenter.title_without_forbidden_words %>
<%= link_to "Read post", post, class: "w-75 p-3 text-#{presenter.css_color} border-#{presenter.css_color}" %>
</p>
どうぞ!
- ビューからすべてのロジックを削除しました
- フォーマットと意思決定の操作に意味のある名前を追加しました
- コードを複製することなく、このクラスを他のビューで再利用できます
これが、Railsでプレゼンターを使用する方法です🙂
サービスオブジェクトの使用方法
コントローラーは他の人に何をすべきかを伝えるだけでよく、ツイートの送信方法、顧客への請求方法、PDFファイルの生成方法についての知識を持ってはなりません。
これらの操作は委任する必要があります サービスオブジェクトに。
私が定義するサービスオブジェクトは、アクションを完了するためのロジックをカプセル化するRubyモジュールです。
例 :
module TwitterService
def self.send_welcome_message(twitter_handle)
client.update("@#{twitter_handle} welcome to 'Oranges & Apples', we hope you enjoy our juicy fruit!")
end
def self.client
@client ||= Twitter::REST::Client.new do |config|
config.consumer_key = "..."
config.consumer_secret = "..."
config.access_token = "..."
config.access_token_secret = "..."
end
end
end
慣例では、これをapp/servicesの下に保存します フォルダ、およびtwitter_service.rbのようなファイル 。
これをどのように使用しますか?
Railsはapp/からすべてを自動ロードするため 、このコードはコントローラーで使用できます。
例 :
class UsersController
def create
# ...
TwitterService.send_welcome_message(user.twitter_handle)
end
end
これが実際のサービスオブジェクトパターンです。
概要
賢明に使用するとプロジェクトのコード品質を向上させるのに役立つ2つの便利なRailsパターンを学びました!
今度はそれらを適用する番です🙂
読んでくれてありがとう。
-
RailsをAWSLambdaにデプロイする
サーバーレスコンピューティングは、サーバーの管理とプロビジョニングの作業をクラウドプロバイダーに任せるのに役立ち、ほとんどのテクノロジーチームにとって急速に重要になっています。 AWS Lambdaは、多くのテクノロジーチームで使用されているサーバーレステクノロジーの一種です。 AWS Lambdaは、NodeJS、Java、Python、Rubyなどのコアプログラミング言語のほとんどをサポートしています。コアプログラミング言語はサポートされていますが、これらの言語で構築されたフレームワークの一部である機能に依存してサーバーレス関数を実行したい場合があります。この投稿では、AWSLambdaで
-
Rails5でのAngularの使用
あなたは前にその話を聞いたことがあります。分散型で完全に機能するバックエンドAPIと、通常のツールセットで作成されたフロントエンドで実行されているアプリケーションがすでにあります。 次に、Angularに移動します。または、AngularをRailsプロジェクトと統合する方法を探しているだけかもしれません。これは、この方法を好むためです。私たちはあなたを責めません。 このようなアプローチを使用すると、両方の世界を活用して、たとえばRailsとAngularのどちらの機能を使用してフォーマットするかを決定できます。 構築するもの 心配する必要はありません。このチュートリアルは、この目的のた