删除多态关联

Deleting polymorphic associations

我通过关注 this great article.

为我的 rails 应用实施了一个收藏系统

这是我的设置:


favorite.rb

class Favorite < ActiveRecord::Base
  belongs_to :user
  belongs_to :favorited, polymorphic: true
end

project.rb

class Project < ActiveRecord::Base
    belongs_to :user

    has_many :favorites, as: :favorited
    has_many :fans, through: :favorites, source: :user 

user.rb

class User < ActiveRecord::Base
  has_many :listings
  has_many :projects
  has_many :favorites
  has_many :favorite_listings, through: :favorites, source: :favorited, source_type: 'Listing'
  has_many :favorite_projects, through: :favorites, source: :favorited, source_type: 'Project'

favorite_projects_controller.rb

class FavoriteProjectsController < ApplicationController
  before_action :set_project
  # before_action :correct_user
  # before_action :authenticate_user!

  def create
    if Favorite.create(favorited: @project, user: current_user)
      redirect_to @project, notice: 'Project has been favorited'
    else
      redirect_to @project, alert: 'Something went wrong...*sad panda*'
    end
  end

  def destroy
    Favorite.where(favorited_id: @project.id, user_id: current_user.id).first.destroy
    redirect_to @project, notice: 'Project is no longer in favorites'
  end

  private

  def set_project
    @project = Project.find(params[:project_id] || params[:id])
  end
end

问题来了。

我有一些最喜欢的项目。

我使用 Project.delete_all 删除了我的项目,而某些项目仍然 "favorited" 但现在我收到错误消息:

 ActionView::Template::Error (undefined method `favorite_projects' for nil:NilClass):

我敢肯定,如果我在删除之前 "unfavorited" 所有这些项目,就不会出现此错误。

有人知道如何解决这个问题吗?

根据 Rails API docs on delete_all:

Deletes the records matching conditions without instantiating the records first, and hence not calling the destroy method nor invoking callbacks. This is a single SQL DELETE statement that goes straight to the database, much more efficient than destroy_all. Be careful with relations though, in particular :dependent rules defined on associations are not honored. Returns the number of rows affected.

我把相关文字加粗了;并进一步在文档中:

If you need to destroy dependent associations or call your before_* or after_destroy callbacks, use the destroy_all method instead.

总而言之,您现在有孤立的 Favorite 条记录。我会启动 rails c 并销毁孤立的记录,下次你 运行 任何 delete 功能时要小心。

您需要设置依赖选项。

has_many :favorites, as: :favorited, dependent: :destroy

在将对象留在数据库中没有意义的任何关联上设置此项。

您不需要在 through has_many 关联上设置它。