I have been doing some mentoring for the firehose project. Recently my student was a bit puzzled as to why she could access an instance variable in a view but not access them in a model after declaring them in a controller. Long story short is that rails doesn’t try to pass instance variables to models (for good reason) so it is not done.

To further explain and shed some light on what I think rails is doing behind the scenes, I decided to whip up this quick example of how one might go about shuffling instance variables around.

To be clear, I am not saying rails actually does things this way, but only that in ruby moving values from one object to another is very easy and so the tendency to do such things happens naturally when using the language. That said, what’s natural for a seasoned ruby programmer could seem downright insane for new developers or developers with limited ruby knowledge.

Please feel free to take the code that follows, put it in a file and run it to see it in action. Try adding instance variables to see that it works without additional implementation code.

class SampleController

attr_accessor :secondvar

def initialize(firstvar: "myfirstvar", secondvar: "mysecondvar")
@firstvar = firstvar
self.secondvar = secondvar
end

def third_var=(thirdvar)
@thirdvar = thirdvar
end

def copy_instance_vars_to_view(view_instance)

self.instance_variables.each do |instance_variable|
view_instance.instance_variable_set(instance_variable, self.instance_variable_get(instance_variable))
end

end

end

class SampleView


def initialize
@fourth_var = "myfourthvar"
end

def print_out_instance_variables
self.instance_variables.each do |instance_variable|
puts self.instance_variable_get(instance_variable)
end
end

end

controller = SampleController.new
controller.third_var = "something custom"

sample_view = SampleView.new

# pass the view into the controller. In rails the controller might
# actually instantiate the view but the same principle applies
controller.copy_instance_vars_to_view(sample_view)

sample_view.print_out_instance_variables