Access objects parent from after_save block
Here is my model:
class Why < ActiveRecord::Base
belongs_to :story
after_save :complete
private
def complete
self.story.update_attributes(:completed => true)
end
end
and controller code:
class WhiesController < ApplicationController
def index
@whies = Why.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @whies }
end
end
def show
@why = Why.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => @why }
end
end
def new
@why = Why.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => @why }
end
end
def create
@story = Story.find(params[:story_id])
@why = @story.build_why(params[:why])
respond_to do |format|
if @why.save
format.html { redirect_to story_path(@why.story) }
format.xml { render :xml => @why, :status => :created, :loca开发者_Go百科tion => @why }
else
format.html { render :action => "new" }
format.xml { render :xml => @why.errors, :status => :unprocessable_entity }
end
end
end
def destroy
@why = Why.find(params[:id])
@why.destroy
respond_to do |format|
format.html { redirect_to(whies_url) }
format.xml { head :ok }
end
end
end
I get an The error occurred while evaluating nil.update_attributes
error coming from the complete after_save method. Can anyone suggest what the problem is, or a workaround?
I'm assuming your Story
class has_one :why
?
From playing around in the console, it looks like your code works perfectly fine, the first time I run it. If I then do it again (using the same @story
), I get your error.
What's happening is that when you execute build_why
, Rails is checking to see if @story
already has another Why
object associated with it, and if so, it removes the association. When it removes this association, it executes the after_save
callback on the previous story, at which point self.story
is now nil
. You'll see this happen in your logs before you ever call @why.save
.
You could probably just wrap your update_attributes
call in a if self.story
conditional, but there may be a bigger flaw with the logic in your program.
Your code is fine, actually.
Try this:
@story = Story.find(params[:story_id])
@why = Why.new(params[:why])
@why.story = @story
精彩评论