如何重构 ActiveRecord 查询?
How to refactor ActiveRecord query?
我在控制器中有一个代码:
def latest
@latest_articles = user_signed_in? ? Article.limit(10).order(id: :desc).pluck(:id, :title) : Article.where("status = ?", Article.statuses[:public_article]).limit(10).order(id: :desc).pluck(:id, :title)
render json: @latest_articles
end
如何重构让它看起来更优雅?
我尝试使用 lambda:
extract = lambda {|a| a.order(id: :desc).pluck(:id, :title)}
Article.limit(10) {|a| a.extract}
但它 returns 仅 Article.limit(10)
UPD:如果用户已登录,我需要获取所有文章的最后 10 篇,如果未登录,则仅获取 public 文章的最后 10 篇。
我会创建一个初始范围,并根据某些条件对其进行修改:
def latest
scope = Article.order(id: :desc)
scope = scope.where(status: Article.statuses[:public_article]) if user_signed_in?
render json: scope.limit(10).pluck(:id, :title)
end
您可以重构为
@lates_articles = Article.all
@lates_articles = @latest_articles.where("status = ?", Article.statuses[:public_article]) unless user_signed_in?
render json: @latest_articles.limit(10).order(id: :desc).pluck(:id, :title)
但是创建模型方法会更好
class Article < ActiveRecord::Base
...
scope :latest, -> {last(10).order(id: :desc)}
def self.public user_signed
if user_signed
all
else
where("status = ?", statuses[:public_article])
end
end
...
end
然后你会像
那样使用它
def latest
render json: Article.public(user_signed_in?).latest.pluck(:id, :title)
end
最终版本:
def latest
scope = Article.order(id: :desc)
scope = scope.shared unless user_signed_in?
render json: scope.limit(10), except: [:body, :created_at, :updated_at]
end
我在控制器中有一个代码:
def latest
@latest_articles = user_signed_in? ? Article.limit(10).order(id: :desc).pluck(:id, :title) : Article.where("status = ?", Article.statuses[:public_article]).limit(10).order(id: :desc).pluck(:id, :title)
render json: @latest_articles
end
如何重构让它看起来更优雅? 我尝试使用 lambda:
extract = lambda {|a| a.order(id: :desc).pluck(:id, :title)}
Article.limit(10) {|a| a.extract}
但它 returns 仅 Article.limit(10)
UPD:如果用户已登录,我需要获取所有文章的最后 10 篇,如果未登录,则仅获取 public 文章的最后 10 篇。
我会创建一个初始范围,并根据某些条件对其进行修改:
def latest
scope = Article.order(id: :desc)
scope = scope.where(status: Article.statuses[:public_article]) if user_signed_in?
render json: scope.limit(10).pluck(:id, :title)
end
您可以重构为
@lates_articles = Article.all
@lates_articles = @latest_articles.where("status = ?", Article.statuses[:public_article]) unless user_signed_in?
render json: @latest_articles.limit(10).order(id: :desc).pluck(:id, :title)
但是创建模型方法会更好
class Article < ActiveRecord::Base
...
scope :latest, -> {last(10).order(id: :desc)}
def self.public user_signed
if user_signed
all
else
where("status = ?", statuses[:public_article])
end
end
...
end
然后你会像
那样使用它def latest
render json: Article.public(user_signed_in?).latest.pluck(:id, :title)
end
最终版本:
def latest
scope = Article.order(id: :desc)
scope = scope.shared unless user_signed_in?
render json: scope.limit(10), except: [:body, :created_at, :updated_at]
end