0

So I'm trying to let the user sort an array of recipes from a link in my view:

<%= link_to "Score", recipes_sort_path, :order => 'score' %>

I send the parameter "score" to my controller method "sort", which looks like this:

  def sort
    if (params[:order] == 'score')
      @recipes.sort_by(&:score)
    end

    respond_to do |format|
      format.html { redirect_to recipes_path }
      format.json { render json: @recipe }
    end
  end

It redirects to the following index method:

  def index
    # If recipes already present, skip following
    if (!@recipes)
      if (params[:search] || params[:tag])
        @recipes = Recipe.search(params[:search], params[:tag])
      else
        @recipes = Recipe.all
      end
    end

    respond_to do |format|
      format.html 
      format.json { render json: @recipe }
    end
  end

The idea was to be redirected to the index view with the sorted list and just render the view. I get no errors, but when I click the link, the page reloads but nothing happens.

The Recipe class looks like this:

class Recipe < ActiveRecord::Base
  attr_accessible :instructions, :name, :slug, :score, :upvotes, :downvotes, :comments, :image

  has_and_belongs_to_many :ingredients
  has_and_belongs_to_many :tags
  has_many :comments  
  belongs_to :user
  delegate :name, :to => :user, :prefix => :user, :allow_nil => true
  mount_uploader :image, ImageUploader

  validates :name, :presence => true

  def score
    score = (self.upvotes - self.downvotes)
  end
end

What am I doing wrong here?

2 Answers 2

2

There's a third option (the first 2 is from ckruse's answer). You can render the index template from the sort action

def sort
  if (params[:order] == 'score')
    @recipes.sort_by!(&:score)
  end

  respond_to do |format|
    format.html { render :index }
    format.json { render json: @recipe }
  end
end

This will use the index template while using @recipes in the sort action. You also save one request because you're not redirecting.

One more thing I'd like to comment on is the link. It should be

<%= link_to "Score", recipes_sort_path(:order => 'score') %>

UPDATE: fetching @recipes. As much as possible, I want sql to do the sorting so that's what I'm going to do here.

def sort
  @recipes = Recipe

  if params[:order] == 'score'
    @recipes = @recipes.order('upvotes - downvotes')
  end

  respond_to do |format|
    format.html { render :index }
    format.json { render json: @recipe }
  end
end
Sign up to request clarification or add additional context in comments.

4 Comments

@recipes is still blank in your example.
I thought it was clear to you how to get @recipes and sort them by score. You're just having trouble showing a sorted @recipes. Give me a minute to update my answer.
I'm afraid it is not clear for the OP. He seems to be new in programming business (sorry :)
Yeah, at least new in this framework, thx. I went with your sort method example. It Works, thanks for your time guys.
0

First of all: sort_by is not „destructive,” it returns a new array. You may want to use sort_by! or save the return value of sort_by into @recipes.

Second: you do not render anything in your sort action at all. If you posted all code, even @recipes is empty. You can do two things:

  • Retreive the data in your sort method as you did in your index method and then call render :index
  • Sort in your index method and do not use a sort method at all. You can route multiple URIs to the same action.

2 Comments

Ok, well I got rid of the sort method, but I'm still doing something wrong. I put the sorting in the index method: ' if (params[:order] == 'score') @recipes.sort! { |r| r.score } end # render view '
Do you call your action with the right parameters? E.g. http://localhost:3000/recipes?order=score?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.