How do I refactor an ActiveRecord request?

I have some code in my 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 do I refactor it to its appearance? I've tried using lambda:

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

      

but it only returns Article.limit(10)

UPD: I need to get the last 10 articles if the user has signed up, and the last 10 of them are only public if not.

+3


source to share


3 answers


I would create a start area and change 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

      

+7


source


You can refactor like

@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 a 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 will use it like

def latest
  render json: Article.public(user_signed_in?).latest.pluck(:id, :title)
end

      

+2


source


final version:

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

      

0


source







All Articles