私は最近、同じ結果を得る2つの方法の選択のジレンマに直面したプロジェクトに取り組んでいました。クラス構造は次のとおりです。Ruby on railsアクティブなレコードのクエリ
class Book < ApplicationRecord
belongs_to :author
end
class Author < ApplicationRecord
has_many :books
end
著者には、姓、名字があります。ある書籍の著者名をインスタンスメソッドとして取得したいと考えています。シンプルなアクティブレコードに関しては
、本は著者に関連付けされているので、以下のように、私たちは本のために著者名を取得することができますが:
例えばBookクラスでは、我々は持っている:
class Book < ApplicationRecord
belongs_to :author
def author_name
"#{author.first_name} #{author.last_name}"
end
end
をと私たちは結果を得る!
しかし、依存性を最小限に抑えるという目標(POODR Book)、将来の変更の容易さ、よりオブジェクト指向の設計によれば、本は著者のプロパティを知るべきではありません。それはインターフェイスによって作成者オブジェクトと対話する必要があります。
だから、著者名を取得する責任者でないようにしてください。著者クラスはすべきです。
class Book < ApplicationRecord
belongs_to :author
def author_name
get_author_name(self.author_id)
end
private
#minimizing class dependecies by providing private methods as external interfaces
def get_author_name(author_id)
Author.get_author_name_from_id(author_id)
end
end
class Author < ApplicationRecord
has_many :books
#class methods which provides a gate-way for other classes to communicate through interfaces, thus reducing coupling.
def self.get_author_name_from_id(id)
author = self.find_by_id(id)
author == nil ? "Author Record Not Found" : "#{author.first_name.titleize} #{author.last_name.titleize}"
end
end
さて、この本はちょうど著者と著者が提供するパブリックインターフェースは確かに優れたデザインです。その性質からフルネームを取得する責任を処理していると相互作用しています。
私は私のコンソールに2つの別々のメソッドとしてのクエリを実行してみました:
class Book < ApplicationRecord
def author_name
get_author_name(self.author_id)
end
def author_name2
"#{author.last_name} + #{author.first_name}"
end
end
が見えます。
私の質問があり
- はAuthor.find_by_id(AUTHOR_ID)は Authorクラス内部で呼び出さ.last_nameとしてレールがブックからのメッセージパッシングを通じて( に同じSQLクエリをBookクラスの内側と呼ばれるauthor.last_nameを変換していクラス)のデータサイズが大きい場合は?
- データサイズが大きい場合、どちらの方がパフォーマンスが良いですか?
- Bookクラスのauthor.last_nameを呼び出すと、デザイン の原則に違反していませんか?
ここで最高の答え - きれいで、きちんとした、自明の説明。 'prefix'と' allow_nil'オプションはこのシナリオに特に適しています。 (あなたはちょっとタイプミスがあると思っています - それは 'join '複数ではないでしょうか?) – SRack
@SRackよく見つかった!今修正されました。 – SteveTurczyn