Rails 重构:更高效的 ActiveRecord 查询和条件测试

Rails Refactoring: More efficient ActiveRecord Queries and Condition Testing

在模型中,我正在尝试 return 条件 ActiveRecord 结果集。如果作者写过书,return 那些。如果作者没有写过任何书,return 篇文章。这有效:

def writings  
  Books.where(author_id: 1).present? ? Books.where(author_id: 1)  : Articles.where(author_id: 2)  
end

如何改进
1.检查条件和设置值时,即不执行两次Books.where查询?
2.从性能的角度来看

我正在努力提高我的效率和风格,经常使用 Style Guide bbatsov or the addition

好吧,首先你现在总是在做 2 个查询。 1 - 获得礼物?,其次获得书籍或文章。

您可以通过更改代码进行改进,以便选择书籍,如果有 none,则选择 returns 篇文章。

def writings  
  books = Books.where(author_id: 1) 
  if books.size > 0 
    books
  else
    Articles.where(author_id: 2)  
  end
end

你可以使用presence方法结合双管道:

def writings
  Books.where(author_id: 1).presence || Articles.where(author_id: 2)
end

来自文档:http://apidock.com/rails/Object/presence

presence() public

Returns the receiver if it’s present otherwise returns nil.

一些示例:

true.presence # => true
1.presence # => 1
false.presence # => nil
[].presence # => nil
''.presence # => nil
User.where(id: -1).presence # => nil

考虑在书籍和文章模型上实施 counter_cache

# class Book
belongs_to :author, counter_cache: true

# class Article
belongs_to :author, counter_cache: true

阅读有关计数器缓存的更多信息here

然后您可以在 运行 任何查询之前检查 books_count 的值。

# class Author
# assumes has_many :books
# and     has_many :articles
def writings
  if books_count.nonzero?
    books
  else
    articles
  end
end