maiconsanson
maiconsanson

Reputation: 249

link_to by association models

I have two models: RECIPE and RECIPE_CATEGORY with "belongs_to" and "has_many" association respectively.

I can list all recipes by category nicely by this url:

http://localhost:3001/recipes/salads

But in my "link_to" that points to recipe list by category seem working only in your own action: recipes#list_by_category.

<%= link_to recipe.recipe_category.name, recipe_category_recipes_path(@recipe_categories) %>

RecipesController

def index  
 @recipes = Recipe.where({ :status_id => 1 }).includes(:chef, :recipe_category).order("updated_at desc").page(params[:page]).per(
end 

def list_by_category
 @recipe_category = RecipeCategory.find_by_name_plural(params[:recipe_category_id])
 @recipes = @recipe_category.recipes.where(:status_id => 1).includes(:chef).order("id desc").page(params[:page]).per(9)
end

Routes

resources :recipes, :id => /[0-9]+/ do
 match 'pagina/:page', :action => :index, :on => :collection # Kaminari
 # list of recipes by category
 get 'recipe_category', :to => 'recipes#list_by_category', :path => ':recipe_category_id', :on => :collection, :recipe_category_id => /[a-z]+/
end

Desired URLS

So, how to build a "link_to" that points to recipes by category across all actions?

Am I clear? Let me know if I not.

Edit

RecipesController

def index
  if params[:category_id]
    @category = Category.find_by_slug(params[:category_id])
    @recipes = @category.recipes.where(:status_id => 1).includes(:chef).order("updated_at desc").page(params[:page]).per(9)
  else
    @recipes = Recipe.where({ :status_id => 1 }).includes(:chef, :category).order("updated_at desc").page(params[:page]).per(9)
    @count_all = Recipe.where({ :status_id => 1 }).count()
  end
end

Routes

resources :categories, :path => "recipes/categories", :only => :index do
  resources :recipes, :path => "", :only => :index do
    match 'pagina/:page', :action => :index, :on => :collection
  end
end
resources :recipes, :path => 'receitas', :id => /[0-9]+/ do
   match 'pagina/:page', :action => :index, :on => :collection
end

URLS

SOLUTION

<%= link_to recipe.name, category_recipes_path(recipe.category.slug) %>

Upvotes: 0

Views: 3556

Answers (1)

numbersnelson
numbersnelson

Reputation: 161

If you want a link to a page that lists all the recipes in a given category, what may work best is to set up the recipes as a nested resource of the recipe_category: http://guides.rubyonrails.org/routing.html#nested-resources

The routing would look something like:

resources :recipe_categories do
  resources :recipes
end

This would allow you to use a link like this:

recipe_category_recipes_path(recipe_category)

which would route to a page that would display all the recipes in the recipe_category. If this is not what you are looking for, please clarify in your question.

Edit:

You could tack on a parameter to the index url, and add a catch in your index that would filter the standard index view down to only the recipes that matched the parameter.

So your rails link to calls would look like this:

recipes_path(:category => @category)
recipes_path(:time => @time)

Which would result in urls that look like this:

localhost:3001/recipes?category=salads
localhost:3001/recipes?time=lunch

And your index method in your recipes controller could be changed to something like this:

def index 
    if params[:category]
        Recipe.where("category = ?", params[:category])
    else if params[:time]
        Recipe.where("time = ?", params[:time])
    else 
        @recipes = Recipe.all
    end
end 

This isn't the prettiest, and I'm not sure how "rails" this approach is, but it works for me in these situations. Let me know if this is what you are looking for, or if I missed again.

Upvotes: 1

Related Questions