【发布时间】:2018-05-10 10:35:22
【问题描述】:
我最近在做一个项目,我面临着在两种获得相同结果的方式之间进行选择的两难境地。这是类结构:
class Book < ApplicationRecord
belongs_to :author
end
class Author < ApplicationRecord
has_many :books
end
作者有名字,姓氏。我想获取给定书籍的作者全名作为实例方法。
在简单的活动记录术语中,由于 book 与 author 相关联,我们可以如下获取一本书的作者姓名:
例如在 Book 类中,我们有:
class Book < ApplicationRecord
belongs_to :author
def author_name
"#{author.first_name} #{author.last_name}"
end
end
我们得到了结果!
但是,根据最小化依赖关系(POODR Book)、未来易于更改和更好的面向对象设计的目标,这本书不应该知道作者的属性。它应该通过接口与作者对象交互。
所以 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
现在,图书只是与 Author 提供的公共接口进行交互,而 Author 负责从其属性中获取全名,这无疑是一个更好的设计。
我尝试在控制台中将查询作为两种不同的方法运行:
class Book < ApplicationRecord
def author_name
get_author_name(self.author_id)
end
def author_name2
"#{author.last_name} + #{author.first_name}"
end
end
看起来两者都运行相同的查询。
我的问题是
- rails 是否将 Book 类中调用的 author.last_name 转换为 与内部调用的 Author.find_by_id(author_id).last_name 相同的 SQL 查询 在数据量较大的情况下,作者类(通过从 Book 类传递的消息)?
- 在数据量更大的情况下,哪一个性能更高?
- 不从 Book 类调用 author.last_name 违反了设计 原则?
【问题讨论】:
标签: ruby-on-rails ruby oop activerecord ruby-on-rails-5