开发者

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜