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
在模型中,我正在尝试 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