Question about variable assignments/scoping after render call

I’ve got a question about how variables are made available to templates. We have a test that looks something like this:

def test_variable_assigned xhr :get, :do_stuff, :id => 1 assert_not_nil assigns(:thing)

end

And our app code looks like this:

class SuperClass < ActionController def do_stuff @parent_model = ParentModel.find(params[:id]) render :template => ‘superclass/do_stuff’ end end

class SubClass < SuperClass def do_stuff super @thing = @parent_model.thing end end

When we run our tests with the code above, it fails saying that assigns(:thing) is nil. If we redefine do_stuff in SubClass to look like:

def do_stuff @thing = ParentModel.find(params[:id]) super end

then the test will pass. Unfortunately, this requires an extra database query to find the parent model twice. Is there a way of telling the view to reload its member variables after render has been called, but still render whatever the chosen template is?

-dmg

David Goudreau wrote:

I've got a question about how variables are made available to templates. We have a test that looks something like this:

  def test_variable_assigned     xhr :get, :do_stuff, :id => 1     assert_not_nil assigns(:thing)   end

And our app code looks like this:

class SuperClass < ActionController   def do_stuff     @parent_model = ParentModel.find(params[:id])      render :template => 'superclass/do_stuff'   end end

class SubClass < SuperClass    def do_stuff       super       @thing = @parent_model.thing    end end

When we run our tests with the code above, it fails saying that assigns(:thing) is nil. If we redefine do_stuff in SubClass to look like:

   def do_stuff       @thing = ParentModel.find(params[:id])       super     end

then the test will pass. Unfortunately, this requires an extra database query to find the parent model twice. Is there a way of telling the view to reload its member variables after render has been called, but still render whatever the chosen template is?

Perhaps write either:

class SuperClass < ActionController    def do_stuff(parent_model = nil)      @parent_model = parent_model      render :template => 'superclass/do_stuff'    end end

class SubClass < SuperClass    def do_stuff      parent_model = ParentModel.find(params[:id])      @thing = parent_model.thing      super(parent_model)    end end

or

class SuperClass < ActionController    def do_stuff(obj = nil)      @parent_model = ParentModel.find(params[:id])      instance_variable_set('@'+obj, @parent_model.send(obj)) if obj      render :template => 'superclass/do_stuff'    end end

class SubClass < SuperClass    def do_stuff      super('thing')    end end