HiveBrain v1.2.0
Get Started
← Back to all entries
patternrubyrailsMinor

Retrieve next card(s) base on the provided parameter

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thecardnextprovidedretrieveparameterbase

Problem

How can I remove the duplicated params[:next_cards]?

def index
  if params[:next_cards] # check nil
    render json: current_user.next_cards(params[:next_cards].to_i),
           status: :ok
  else
    render json: current_user.cards, status: :ok
  end
end


Inside the user.rb module,

def next_cards(num_of_cards=nil)
    if num_of_cards
      cards.next_cards.limit(num_of_cards)
    else
      cards.next_cards
    end
  end


Inside the card.rb module,

def self.next_cards
    joins(:meta_sm2).merge(MetaSm2.next_cards).order('RANDOM()')
  end


Inside the meta_sm2.rb model,

scope :next_cards, -> { where('next_repetition <= :current_time', current_time: Time.now) }

Solution

Ok, in response to the conversation in comments, Here's my suggested first step:

def index
    render json: cards, status: :ok
  end

  private

  def cards
    if next_cards
      current_user.next_cards(next_cards.to_i)
    else
      current_user.cards
    end
  end

  def next_cards
    params[:next_cards]
  end


the larger issue here though is that you are essentially using params[:next_cards] as a switch for what should essentially be two controller actions. the latter being the index action of the cards controller, and the former being something along the lines of user/next_cards/:id . Possibly a next cards controller. The show action of which could look something like

routes.rb:

resource :next_cards, only: :show


app/controllers/next_cards_controller.rb:

def show
  render json: current_user.next_cards(params[:id])
end


controllers don't have to have a 1 to 1 mapping with models. This way takes advantage of rails routing to validate that params[:id] will always be present. thereby eliminating the need for a nil check.

Obviously this could take more time as your views will need to be updated to reflect the new route. If it's a greenfield app, go ahead and do it right now. If it's an old, bloated codebase, start small with the refactor and do it in chunks.

Code Snippets

def index
    render json: cards, status: :ok
  end

  private

  def cards
    if next_cards
      current_user.next_cards(next_cards.to_i)
    else
      current_user.cards
    end
  end

  def next_cards
    params[:next_cards]
  end
resource :next_cards, only: :show
def show
  render json: current_user.next_cards(params[:id])
end

Context

StackExchange Code Review Q#155810, answer score: 4

Revisions (0)

No revisions yet.