Seifer Seifer - 6 months ago 35
Ruby Question

Rails: Set up favorite recipe for user but keep getting same error

As a user I want to be able to add a recipe to my Favorites. Unfortunately when I try to add a recipe to my Favorites I get the following

error: Recipe(#69883866963220) expected, got NilClass(#46922250887180)
.

I followed this 'tutorial' as a guideline

Somehow it is not able to add it to the user's Favorites. When I use
Rails C
and type in
User.find(1).favorites
, it returns me an empty array.

Who can help me to solve the issue? Thank you in advance!

My models:

class FavoriteRecipe < ActiveRecord::Base
belongs_to :recipe
belongs_to :user
end





class User < ActiveRecord::Base
has_many :recipes

# Favorite recipes of user
has_many :favorite_recipes # just the 'relationships'
has_many :favorites, through: :favorite_recipes, source: :recipe # the actual recipes a user favorites
end

class Recipe < ActiveRecord::Base
belongs_to :user

# Favorited by users
has_many :favorite_recipes # just the 'relationships'
has_many :favorited_by, through: :favorite_recipes, source: :user # the actual users favoriting a recipe
end


My recipecontroller.rb:

def show
@review = Review.new
@recipe = Recipe.find(params[:id])
@user = User.find(@recipe.user_id)
@full_name = @recipe.user.first_name + " " + @recipe.user.last_name
# @reviews = @recipe.reviews.page(params[:page]).order('created_at DESC')
end

# Add and remove favorite recipes
# for current_user
def favorite
type = params[:type]
if type == "favorite"
current_user.favorites << @recipe
redirect_to :back, notice: 'You favorited #{@recipe.name}'

elsif type == "unfavorite"
current_user.favorites.delete(@recipe)
redirect_to :back, notice: 'Unfavorited #{@recipe.name}'

else
# Type missing, nothing happens
redirect_to :back, notice: 'Nothing happened.'
end
end


Routes:

resources :recipes, only: [:index, :show] do
put :favorite, on: :member
end


My view: app/views/recipes/show.html.erb

<% if current_user.favorites.exists?(id: @recipe.id) %>
<%= link_to favorite_recipe_path(@recipe, type: "unfavorite"), method: :put do %>
<ul class="list-inline product-controls">
<li><i class="fa fa-heart"></i></li>
</ul>
<% end %>
<% else %>
<%= link_to favorite_recipe_path(@recipe, type: "favorite"), method: :put do %>
<ul class="list-inline product-controls">
<li><i class="fa fa-heart"></i></li>
</ul>
<% end %>
<% end %>

Answer

According to your relationship you need recipe object to assign to user. So need to first find that object and then assign it to user.

def favorite
    @recipe = Recipe.find(params[:id])
    type = params[:type]
    if type == "favorite"
      current_user.favorites << @recipe
      redirect_to :back, notice: 'You favorited #{@recipe.name}'

    elsif type == "unfavorite"
      current_user.favorites.delete(@recipe)
      redirect_to :back, notice: 'Unfavorited #{@recipe.name}'

    else
      # Type missing, nothing happens
      redirect_to :back, notice: 'Nothing happened.'
    end
end
Comments