简体   繁体   English

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

[英]Rails Refactoring: More efficient ActiveRecord Queries and Condition Testing

In a model I am trying to return a conditional ActiveRecord result set. 在模型中,我尝试返回条件ActiveRecord结果集。 If the author has written books, return those. 如果作者写过书,请将其退还。 If the author hasn't written any books, return articles. 如果作者还没有写任何书,请退回文章。 This works: 这有效:

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

How can this be improved 如何改善
1. When checking conditions and setting values, ie not executing the Books.where query twice? 1.检查条件和设置值时,即不执行两次Books.where查询?
2. From a performance standpoint 2.从性能的角度

I'm working on improving my efficiency and style and often use either Style Guide bbatsov or the addition . 我正在努力提高效率和样式,经常使用“ 样式指南” bbatsov其他 样式

You can use the presence method combined with a double pipe: 您可以将presence方法与双管道结合使用:

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

From the documentation: http://apidock.com/rails/Object/presence 从文档中: http : //apidock.com/rails/Object/presence

presence() public

Returns the receiver if it's present otherwise returns nil . 返回接收器(如果存在),否则返回nil

Some examples: 一些例子:

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

Consider implementing counter_cache on both Book and Article models. 考虑在Book和Article模型上实现counter_cache

# class Book
belongs_to :author, counter_cache: true

# class Article
belongs_to :author, counter_cache: true

Read more about counter caching here . 在此处阅读有关计数器缓存的更多信息。

Then you can inspect the value of books_count before running any queries. 然后,您可以在运行任何查询之前检查books_count的值。

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

Well, first of all you are now always doing 2 queries. 好吧,首先,您现在总是在执行两个查询。 1 - to get present?, second to get either books or Articles. 1-获得礼物?其次获得书籍或文章。

You can improve by changing code so that is selects books and if there are none, then returns articles. 您可以通过更改代码来进行改进,以便选择书籍;如果没有书籍,则返回文章。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM