Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to refactor ActiveRecord query?

I have a code in controller:

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

How to refactor it to looks elegant? I tried using lambda:

extract = lambda {|a| a.order(id: :desc).pluck(:id, :title)}
Article.limit(10) {|a| a.extract}

but it returns only Article.limit(10)

UPD: I need to get last 10 of all articles if user is signed in, and last 10 of only public ones if not.

like image 760
y.bregey Avatar asked Jan 27 '26 12:01

y.bregey


2 Answers

I would create an initial scope, and modify it based on some conditions:

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
like image 55
Yury Lebedev Avatar answered Jan 30 '26 02:01

Yury Lebedev


You could refactor as

@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)

But it would be better to create model method

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

Then you would use it like

def latest
  render json: Article.public(user_signed_in?).latest.pluck(:id, :title)
end
like image 45
Nermin Avatar answered Jan 30 '26 02:01

Nermin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!