undefined method `destroy' on Public Activity

狂风中的少年 提交于 2019-12-18 18:28:22

问题


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

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

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

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

here's my Screens Controller:

  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

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

I read on Railscast:

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

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

What am i missing?

Informations below

screen.rb

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

comment.rb

belongs_to :user
belongs_to :screen

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

  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

That's how my Screen Controller Destroy Action looks like right now:

  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

Again the same error:


回答1:


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

First you can remove the references to activities in your screens_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

Should be outside of your respond to block

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

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.



来源:https://stackoverflow.com/questions/23046076/undefined-method-destroy-on-public-activity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!