2014-04-13 2 views
1

사용자의 화면에 대해 언급 할 수 있으며이 PublicActivity 추적 있어요에 '파괴 :정의되지 않은 방법은`공개 활동

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

및 코멘트 의존 : 화면 모델을 파괴한다.

그러나 화면을 삭제할 때 주석이 삭제되는 동안 해당 주석에 대한 PublicActivity의 레코드는 계속 존재합니다.

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 method이 전무에 대한 '파괴 받고 있어요 : NilClass`

여기 내 Screens Controller입니다.

나는 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

내가 무엇을 놓치고?

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

,174 내 스크린 컨트롤러 액션을 파괴하는 방법은
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 

지금과 같습니다

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 

다시 같은 오류 :이 테스트되지 않은 상태입니다

enter image description here

+0

여기서'@ screen'을 가져옵니다. 그의 객체는 무제한 객체이고 그 객체를 파괴하려고합니다. –

+0

'@screen = Screen.find (params [: id])?당신이 바닥에 set_screen에 그것을 가지고 있지 않는 한. 하지만 분명히 변수'@ screen'을 어디에도 만들지는 않습니다. –

+0

@MohamedElMahallawy Set_screen에 있습니다. 내 질문 편집 –

답변

5

하지만이 무엇을이다 나는 네가해야한다고 생각해.

먼저 #이 comments_controller 번호가

@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 

는 귀하의 의견에

다음을 차단하기 위해 응답 외부이어야한다 파괴에 그런

을 파괴하여 screens_controller에 활동에 대한 참조를 제거 할 수 있습니다 다음과 같이해야합니다.

#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

중에 호출되는 기본 루비 파괴 메서드를 재정의하지만이 작업을 수행해야합니다.

+0

"before_destroy 메서드를 호출하면 기본 루비 파괴 메서드가 재정의됩니다." Epicly 근무했습니다! –

+1

@TheMiniJohn은'comment.rb'에서 제 편집 내용을 봅니다. 안전을 위해'if activity.present? '를 추가하여 활동을 찾도록하십시오. 그렇지 않으면 오류가 발생합니다. – itsthewrongway

+1

삭제해서는 안되는 활동을 삭제할 경우 의도하지 않은 결과가 발생할 수 있으므로 위의 내용을주의하십시오. 다형성이기 때문에 동일한 'trackable_id'를 가진 여러 활동이있을 수 있습니다. 대신 'activity = PublicActivity :: Activity.find_by (trackable_id : self.id, trackable_type : self.class.name)'로 활동을 찾을 것입니다. –

관련 문제