I'm creating a web application that features a database of recipes. I am working on implementing a feature to allow users to add recipes to their favorites list and know this involves Active Record associations. The following is what I tried. Unfortunately, I received the following error message.
Could not find the source association(s) :favorite or :favorites in model FavoriteRecipe. Try 'has_many :favorites, :through => :favorite_recipes, :source => <name>'. Is it one of :recipe or :user?
I've searched RubyonRails guides under ActiveRecord Associations and tried this code, but it raised the above error.
Here is my Recipe model, Recipe.rb
class Recipe < ActiveRecord::Base
belongs_to :user
has_many :favorite_recipes
has_many :favorited_by, through: :favorite_recipes, source: :user
end
Here is my User model, User.rb
class User < ActiveRecord::Base
has_many :recipes
has_many :favorite_recipes
has_many :favorites, through: :favorite_recipes
end
Here is my favorite recipe model, favorite_recipe.rb
class FavoriteRecipe < ActiveRecord::Base
belongs_to :recipe
belongs_to :favorite
belongs_to :user
end
Here is my favorite recipe migration file
class CreateFavoriteRecipes < ActiveRecord::Migration
def change
create_table :favorite_recipes do |t|
t.string :recipe_id
t.string :integer
t.string :user_id
t.string :integer
t.timestamps
end
end
end
Playing around in Rails Console, I tried the following
FavoriteRecipe.table_name
=> "favorite_recipes"
FavoriteRecipe.attribute_names
=> ["id", "recipe_id", "integer", "user_id", "created_at", "updated_at"]
FavoriteRecipe.primary_key
=> "id"
FavoriteRecipe.column_names
=> ["id", "recipe_id", "integer", "user_id", "created_at", "updated_at"]
FavoriteRecipe.connected?
=> "true"
Here is my routes.rb file
get "users/new"
resources :recipes do
put :favorite, on: :member
end
resources :users
resources :sessions, only: [:new, :create, :destroy]
get 'static_pages/about'
get 'static_pages/contact'
get 'static_pages/help'
match '/signup', to: 'users#new', via: 'get'
match '/signin', to: 'sessions#new', via: 'get'
match '/signout', to: 'sessions#destroy', via: 'delete'
When running rake routes, here is my output
users_new_path GET /users/new(.:format) users#new
favorite_recipe_path PUT /recipes/:id/favorite(.:format) recipes#favorite
recipes_path GET /recipes(.:format) recipes#index
POST /recipes(.:format) recipes#create
new_recipe_path GET /recipes/new(.:format) recipes#new
edit_recipe_path GET /recipes/:id/edit(.:format) recipes#edit
recipe_path GET /recipes/:id(.:format) recipes#show
PATCH /recipes/:id(.:format) recipes#update
PUT /recipes/:id(.:format) recipes#update
DELETE /recipes/:id(.:format) recipes#destroy
users_path GET /users(.:format) users#index
POST /users(.:format) users#create
new_user_path GET /users/new(.:format) users#new
edit_user_path GET /users/:id/edit(.:format) users#edit
user_path GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
sessions_path POST /sessions(.:format) sessions#create
new_session_path GET /sessions/new(.:format) sessions#new
session_path DELETE /sessions/:id(.:format) sessions#destroy
static_pages_about_path GET /static_pages/about(.:format) static_pages#about
static_pages_contact_pathGET /static_pages/contact(.:format static_pages#contact
static_pages_help_path GET /static_pages/help(.:format) static_pages#help
signup_path GET /signup(.:format) users#new
signin_path GET /signin(.:format) sessions#new
signout_path DELETE /signout(.:format) sessions#destroy
When a user clicks on "show", it shows the particular recipe and has a link where you can add it to your favorites list. Here is my recipes/show.html.erb file
<h3>Recipe</h3>
<ul id = 'view'>
<li><strong>Title:</strong> <%= @recipe.title %></li>
<li><strong>Console:</strong> <%= @recipe.console %></li>
<li><strong>Genre:</strong> <%= @recipe.genre %></li>
<li><strong>Release Date:</strong> <%= @recipe.released_on %></li>
</ul>
<p>
<%= link_to 'Add to Favorites', favorite_recipe_path(@recipe, type: 'favorite'), method: :put, id: 'favorites' %>
</p>
<p>
<%= link_to 'Back', recipes_path, id: 'back' %>
</p>
I defined the following method in my recipes_controller.rb file
def favorite
type = params[:type]
if type == "favorite"
current_user.favorites << @recipe
redirect_to :back, notice: "#{@recipe.name} successfully added to your favorites!"
elsif type == "unfavorite"
current_user.favorites.delete(@recipe)
redirect_to :back, notice: "#{recipe.name} removed from your favorites"
else
redirect_to :back, notice: 'No change'
end
end
My apologies. I am a beginner in Ruby and still don't quite understand Active Record Associations. But any help as always is greatly appreciated.
I'm not sure if this reflects your actual migration, but it is completely wrong:
class CreateFavoriteGames < ActiveRecord::Migration
def change
create_table :favorite_games do |t|
t.string :game_id
t.string :integer
t.string :user_id
t.string :integer
t.timestamps
end
end
end
Should be:
class CreateFavoriteGames < ActiveRecord::Migration
def change
create_table :favorite_games do |t|
t.integer :game_id
t.integer :user_id
t.integer :favorite_id
t.timestamps
end
add_index :favorite_games, :game_id
add_index :favorite_games, :user_id
add_index :favorite_games, :favorite_id
add_index :favorite_games, [:game_id, :user_id, :favorite_id], unique: true
end
end