[英]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.