公共活动上未定义的方法“销毁" [英] undefined method `destroy' on Public Activity

查看:18
本文介绍了公共活动上未定义的方法“销毁"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

用户可以在屏幕上发表评论并由 PublicActivity 跟踪:

User's can comment on a Screen and it's tracked by PublicActivity :

@comment.create_activity :create, owner: current_user, recipient: @comment.screen.user

并且注释是依赖的::destroy 在屏幕模型上.

and the comments are dependent: :destroy on the screen model.

但是当我删除一个屏幕时,当评论被删除时,该评论的 PublicActivity 记录仍然存在.

But when i delete a screen, while the comments are deleted, the Record from PublicActivity for that comment still exists.

这是我的屏幕控制器:

  def destroy
    @activity = PublicActivity::Activity.find_by_trackable_id(params[:id])
    @activity.destroy #<-- Heres the Problem
    @screen.destroy
    respond_to do |format|
      format.html { redirect_to root_path }
      format.json { head :no_content }
    end
  end

但是在删除屏幕时,我得到了 undefined methoddestroy' for nil:NilClass`.

But upon deleting a Screen, i'm getting undefined methoddestroy' for nil:NilClass`.

我在 Railscast 上读到:

I read on Railscast:

这是因为在对象创建后调用了 create_activity 方法被摧毁了.

it was due to calling the create_activity method after the object had been destroyed.

根据 gem 维护者的说法,您只需假设记录将被销毁,并在销毁前调用 create_activity

According to the gem maintainers, you simply have to assume the record will be destroyed, and call create_activity before the destroy

我错过了什么?

以下信息

screen.rb

belongs_to :user
has_many :comments, :dependent =>  :destroy

comment.rb

belongs_to :user
belongs_to :screen

screens_contoller.rb

screens_contoller.rb

  def create
    @screen = current_user.screens.build(screen_params)
    respond_to do |format|
      if @screen.save
         format.html { redirect_to @screen, notice: 'You successfully uploaded your Screenshot.' }
        format.json { render action: 'show', status: :created, location: @screen }
        current_user.add_points(2, 'Points for Uploading a Screenshot')
      else
        format.html { render action: 'new' }
        format.json { render json: @screen.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @activity = PublicActivity::Activity.find_by_trackable_id(params[:id])
    @activity.destroy
    @screen.destroy
    respond_to do |format|
      format.html { redirect_to root_path }
      format.json { head :no_content }
      current_user.substract_points(1, "Substraction for Deleting a Screenshot")
    end
  end

comments_controller.rb

comments_controller.rb

  def create
    @screen = Screen.find(params[:screen_id])
    @comment = current_user.comments.build(comment_params)
    @comment.screen_id = @screen.id
    respond_to do |format|
      if @comment.save
        # Create Record for Public Activity
        @comment.create_activity :create, owner: current_user, recipient: @comment.screen.user
        format.html { redirect_to @screen, notice: 'Comment was successfully created.' }
        format.json { render action: 'show', status: :created, location: @comment }
      else
        format.html { render action: 'new' }
        format.json { render json: @comment.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @comment.destroy
    respond_to do |format|
      @activity = PublicActivity::Activity.find_by_trackable_id(params[:id])
      @activity.destroy
      format.html { redirect_to :back }
      format.json { head :no_content }
    end
  end

这就是我的 Screen Controller Destroy Action 现在的样子:

  def destroy
    @screen = current_user.screens.find(params[:id])
    @activity = PublicActivity::Activity.find_by_trackable_id(params[:id])
    @activity.destroy
    @screen.destroy
    current_user.substract_points(1, "Substraction for Deleting a Screenshot")
    respond_to do |format|
      format.html { redirect_to root_path }
    end
  end

同样的错误:

推荐答案

这未经测试,但我认为您应该这样做.

This isn't tested, but this is what I think you should do.

首先,您可以在screens_controller#destroy 中删除对活动的引用

First you can remove the references to activities in your screens_controller#destroy

然后在您的comments_controller#destroy

Then in your comments_controller#destroy

  @comment = current_user.comments.find(params[:id])
  @activity = PublicActivity::Activity.find_by(trackable_id: (params[:id]), trackable_type: controller_path.classify)
  @activity.destroy
  @comment.destroy

应该在您的响应块之外

接下来在你的评论模型中你应该做这样的事情:

Next in your comments model you should do something like this:

#comment.rb

private

before_destroy :find_and_destroy_comments

def find_and_destroy_comments
  activity = PublicActivity::Activity.find_by(trackable_id: self.id, trackable_type: self.class.name)
  if activity.present?
    activity.destroy
  end
end

调用 before_destroy 方法会覆盖在 dependent: :destroy

calling the before_destroy method overrides the default ruby destroy method that is called during dependent: :destroy

让我知道这是否有效,但它应该.

Let me know if this works, but It should.

这篇关于公共活动上未定义的方法“销毁"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆