Adding variables to a binding

I need to run an ERB template (a normal Rails view template) in a Rails model (and then write the result to a file). The problem is that I need to run it in the scope of the calling controller. So I was thinking of creating a binding in the controller and pass into the model and use the binding there. I do however need to add variables from the model scope into the binding. How do I do this? Thought of using eval with the binding but it only seems to take an input string to eval (a block would have been nice I think).

The reason I do this is that the model in question is a STI model and each sub class may need to add different variables. If you can think of a better way to accomplish what I want I'll be glad to hear :slight_smile:

Thanks,

/Marcus

If I understand correctly, you want something like this:

  def outerscope
     innerscope(binding)
     p foo,bar,baz #problematic
  end

  def innerscope(bdg)
     eval "foo=bar=baz=1", binding
  end

This works, sort of. Unfortunately, ruby's local variables are
lexically scoped, which means that once you get back to outerscope,
foo, bar, and baz (which _are_ now in outerscope's binding) won't be
recognized as local variables. (Unless you use eval again to get at
them....) For most purposes, they are unusable.

How about this instead:

  def outerscope
     vars={}
     innerscope(vars)
     p vars[:foo],vars[:bar],vars[:baz]
  end

  def innerscope(vars)
     vars[:foo]=vars[:bar]=vars[:baz]=1
  end

···

On 2/11/06, marcus <m-lists@bristav.se> wrote:

I need to run an ERB template (a normal Rails view template) in a Rails
model (and then write the result to a file). The problem is that I need
to run it in the scope of the calling controller. So I was thinking of
creating a binding in the controller and pass into the model and use the
binding there. I do however need to add variables from the model scope
into the binding. How do I do this? Thought of using eval with the
binding but it only seems to take an input string to eval (a block would
have been nice I think).

The reason I do this is that the model in question is a STI model and
each sub class may need to add different variables. If you can think of
a better way to accomplish what I want I'll be glad to hear :slight_smile:

Dňa Sobota 11 Február 2006 23:12 marcus napísal:

I need to run an ERB template (a normal Rails view template) in a Rails
model (and then write the result to a file). The problem is that I need
to run it in the scope of the calling controller. So I was thinking of
creating a binding in the controller and pass into the model and use the
binding there. I do however need to add variables from the model scope
into the binding. How do I do this? Thought of using eval with the
binding but it only seems to take an input string to eval (a block would
have been nice I think).

The reason I do this is that the model in question is a STI model and
each sub class may need to add different variables. If you can think of
a better way to accomplish what I want I'll be glad to hear :slight_smile:

Thanks,

/Marcus

I -think- instance variables get exported from the ERB template into the
calling method.

David Vallner

Caleb Clausen skrev:

How about this instead:

  def outerscope
     vars={}
     innerscope(vars)
     p vars[:foo],vars[:bar],vars[:baz]
  end

  def innerscope(vars)
     vars[:foo]=vars[:bar]=vars[:baz]=1
  end

The problem is that ERB#result(binding) takes a binding so I need the binding. The templates used in this case relies on Rails rules (member variables in a controller are available in the ERB template) and I need to create a binding containing everything from the controller scope (and then add the new needed stuff from the model).

What about passing a block from outer scope and call it from inner scope and pass in a Hash with variables from the inner scope, then loop over the variables and add those as instance members (using instance_eval), create the binding (inside the block) and then invoke ERB.result. Could that work?

/Marcus

···

On 2/11/06, marcus <m-lists@bristav.se> wrote: