Ruby on Rails ActiveRecord :: AssociationTypeMismatch与关联

时间:2016-12-11 21:21:13

标签: ruby-on-rails ruby activerecord

我正在尝试创建一个非常基本的测试应用程序,以允许用户将食谱添加到他们的“收藏夹”中。 我已经设置了用户,食谱和喜欢的模型,我基本上遵循以下顶部评论中发布的指南: Implement "Add to favorites" in Rails 3 & 4

但是,我在RecipesController#favorite中收到“ActiveRecord :: AssociationTypeMismatch”错误。

以下是我的模特:

    class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
  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

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

这是控制器:

class RecipesController < ApplicationController
  before_action :set_recipe, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!

  # GET /recipes
  # GET /recipes.json

  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

  def index
    @recipes = Recipe.all
  end

  # GET /recipes/1
  # GET /recipes/1.json
  def show
  end

  # GET /recipes/new
  def new
    @recipe = Recipe.new
  end

  # GET /recipes/1/edit
  def edit
  end

  # POST /recipes
  # POST /recipes.json
  def create
    @recipe = Recipe.new(recipe_params)

    respond_to do |format|
      if @recipe.save
        format.html { redirect_to @recipe, notice: 'Recipe was successfully created.' }
        format.json { render :show, status: :created, location: @recipe }
      else
        format.html { render :new }
        format.json { render json: @recipe.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /recipes/1
  # PATCH/PUT /recipes/1.json
  def update
    respond_to do |format|
      if @recipe.update(recipe_params)
        format.html { redirect_to @recipe, notice: 'Recipe was successfully updated.' }
        format.json { render :show, status: :ok, location: @recipe }
      else
        format.html { render :edit }
        format.json { render json: @recipe.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /recipes/1
  # DELETE /recipes/1.json
  def destroy
    @recipe.destroy
    respond_to do |format|
      format.html { redirect_to recipes_url, notice: 'Recipe was successfully destroyed.' }
      format.json { head :no_content }
    end
  end


  private
    # Use callbacks to share common setup or constraints between actions.
    def set_recipe
      @recipe = Recipe.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def recipe_params
      params.require(:recipe).permit(:user_id, :title)
    end
end

我在视图中使用的代码,用于启用收藏夹添加:

<% if current_user %>
  <%= link_to "favorite", favorite_recipe_path(@recipe, type: "favorite"), method: :put %>
  <%= link_to "unfavorite", favorite_recipe_path(@recipe, type: "unfavorite"), method: :put %>
<% end %>

我收到的完整错误:

    ActiveRecord::AssociationTypeMismatch in RecipesController#favorite
    Recipe(#70327608659260) expected, got NilClass(#17178580)

    Extracted source (around line #11):

09           type = params[:type]
10        if type == "favorite"
11       current_user.favorites << @recipe
          redirect_to :back, notice: 'You favorited #{@recipe.name}'

        elsif type == "unfavorite"

非常感谢任何帮助。 非常感谢你

1 个答案:

答案 0 :(得分:1)

您的@recipenil ...您还需要为@recipe操作设置favorite

class RecipesController < ApplicationController
  before_action :set_recipe, only: [:show, :edit, :update, :destroy, :favorite]
...