How get instance of form_for object from @object_name?

I have a custom form builder. In it I have a method for retrieving
validation error messages.

Currently it gets used like this:

<% form_for :my_obj…
<%= form.draw_invalid_msg(my_obj.errors[:userHosts]) %>

I would like to reduce that to this:

<%= form.draw_invalid_msg(:userHosts) %>

My method code would that start with something like this:

def draw_invalid_msg(field_name)
invalid_messages = @object_name.errors[field_name]

Well, that doesn’t work, of course, because @object_name is just a
symbol, not the actual AR object data. So, yes, I could explicitly
pass in the obj to start with, but that’s exactly what I am trying to
eliminate.

So, what introspective tricky can be used to yield access to the
actual object within :my_obj via the @object_name ivar value?

Make sense?

– gw

I think this will get it:

invalid_messages = instance_eval("@#{object_name}").errors[field_name]

Nope. I think your idea would have needed @object_name not just
object_name, but that didn’t work either.

I tried a few versions with eval too, but no luck so far.

– gw

On 21 May 2008, at 05:58, Greg W. wrote:

Nope. I think your idea would have needed @object_name not just
object_name, but that didn’t work either.

I tried a few versions with eval too, but no luck so far.

form.object :slight_smile:

Fred

Oops. Not so tricky. form doesn’t propogate into the custom builder
methods – which makes sense. So, I would guesd that form.object
works inside the form, but it doesn’t inside a custom builder method.

def draw_invalid_msg(field_name)
invalid_messages = form.object.errors[field_name]

That’s what I tried, which I should have recognized wasn’t going to
work.

– gw

On 21 May 2008, at 09:07, Greg W. wrote:

is this in a form builder ? in which case self is the form build, so
just object.errors should work

Fred

On May 20, 2008, at 11:24 PM, Frederick C. wrote:

form.object :slight_smile:

ooOOOooo. Tricky! :stuck_out_tongue:

– gw (egads)

On 21 May 2008, at 09:26, Greg W. wrote:

This would be greatly simplified if the form builder had access to
the originating controller’s instance variables, but that appears to
not be the case (though I ran into false data on ivar scope before :wink:

it’s a completely distinct object so would be a little crazy.

Anyway, it would seem that any variable usable within my form builder
method must be an instance var like @object_name, and not just a
local var like object ?

it’s @object, but there’s an accessor, so object should work. There
are plenty of built in helpers using @object so object/@object should
work, unless you’re doing something really funny,

Fred

On May 21, 2008, at 1:12 AM, Frederick C. wrote:

def draw_invalid_msg(field_name)
invalid_messages = form.object.errors[field_name]
That’s what I tried, which I should have recognized wasn’t going to
work.

is this in a form builder ? in which case self is the form build, so
just object.errors should work

Yes, it is. Nope, it didn’t.

Currently, my baseline code gets used like this:

<% form_for :my_obj.....
<%= form.draw_invalid_msg(my_obj.errors[:userHosts]) %>

I would like to reduce that to this:

<%= form.draw_invalid_msg(:userHosts) %>

My custom form builder method would start with something like this:

def draw_invalid_msg(field_name)
  invalid_messages = @object_name.errors[field_name]

…but I need a replacement for @object_name. form.object, or just
object doesn’t work.

This would be greatly simplified if the form builder had access to
the originating controller’s instance variables, but that appears to
not be the case (though I ran into false data on ivar scope before :wink:

Anyway, it would seem that any variable usable within my form builder
method must be an instance var like @object_name, and not just a
local var like object ?

– gw

On May 21, 2008, at 1:30 AM, Frederick C. wrote:

My custom form builder method would start with something like this:

def draw_invalid_msg(field_name)
invalid_messages = @object_name.errors[field_name]

…but I need a replacement for @object_name. form.object, or just
object doesn’t work.

Anyway, it would seem that any variable usable within my form builder
method must be an instance var like @object_name, and not just a
local var like object ?

it’s @object, but there’s an accessor, so object should work. There
are plenty of built in helpers using @object so object/@object should
work, unless you’re doing something really funny,

Just to be sure – are you talking Rails 2.0? I am using 1.2.6.

As far as I can tell, I’m not doing anything weird. Generated a form
builder, have a number of HTML drawing methods that I use just fine.
Nothing tricky, just some simple string rendering.

Just to see if @object exists, I used debug(@object) right inside the
form_for boundaries (not one of my builder methods), and I get
nothing. if I debug (object) then I get local var not defined error.
If I debug (my_obj) then I get a full object dump. So it seems to me
dey ain’t no @object. So either it’s Rails 2 or I broke it.

– gw

On 21 May 2008, at 09:49, Greg W. wrote:

Anyway, it would seem that any variable usable within my form
builder
method must be an instance var like @object_name, and not just a
local var like object ?

it’s @object, but there’s an accessor, so object should work. There
are plenty of built in helpers using @object so object/@object should
work, unless you’re doing something really funny,

Just to be sure – are you talking Rails 2.0? I am using 1.2.6.

Ah yes, I almost certainly am. No clue what’s going on in 1.2.6,
although a cursory look at the source suggests it’s the same

As far as I can tell, I’m not doing anything weird. Generated a form
builder, have a number of HTML drawing methods that I use just fine.
Nothing tricky, just some simple string rendering.

Just to see if @object exists, I used debug(@object) right inside the
form_for boundaries (not one of my builder methods), and I get
nothing. if I debug (object) then I get local var not defined error.
if you mean

<% form_for … do |f| %>
<%= object %>
<% end %>
then that won’t work (since object is evaluated in the context of the
view, not in the context of the form builder (f.object should work
there though).

If I debug (my_obj) then I get a full object dump. So it seems to me
dey ain’t no @object. So either it’s Rails 2 or I broke it.

Fred

form_for boundaries (not one of my builder methods), and I get
nothing. if I debug (object) then I get local var not defined error.
if you mean

<% form_for … do |f| %>
<%= object %>
<% end %>
then that won’t work (since object is evaluated in the context of the
view, not in the context of the form builder (f.object should work
there though).

<% form_for :edp_target,
:url => {:action => :record_editor},
:builder => EdpBuilder do |form| %>

 <%= debug() %>

where () = (@object), (form.object), or (object) – none yield any data.

So, @object appears to be 2.0-specific.

What I do have is @object_name, but I can’t figure out how to
leverage that into a reference to the actual data held in @edp_target
to which :edp_target is the name of.

It’s not critical. I was just hoping to simplify something.

– gw

On May 21, 2008, at 3:36 AM, Frederick C. wrote:

On 21 May 2008, at 11:25, Greg W. wrote:

Just to be sure – are you talking Rails 2.0? I am using 1.2.6.

Just to see if @object exists, I used debug(@object) right inside
the
form_for boundaries (not one of my builder methods), and I get
nothing. if I debug (object) then I get local var not defined error.

will populate object properly with @edp_target (and with 2.0, just
form_for @edp_target would work)

Ah. OK, after more tinkering using this version:

<% form_for :edp_target, @edp_target,

form.object is populated within the form_for boundaries, but @object
is not. However, in my EdpBuilder methods, @object is available–
which is all I need. From there, I can do what I need.

Thanks for sticking with this Fred – as always your vantage point
has helped. I’m going to owe you a nice dinner someday.

– greg

Nope. I think your idea would have needed @object_name not just
object_name, but that didn’t work either.

I tried a few versions with eval too, but no luck so far.

– gw

It should have been the symbol of the name of the object. The
instance_eval statment would get inspected into @some-named-object via
string interpolation and the instance_eval would have evaluated that
against the instance.

FWIW, I’ve used that trick to do something very similar to what you’re
after. I built a little lib of methods that allow me to use ruby
syntax to generate extjs compatible javascript. In my scenario I was
emulating form_for with ext_form_for and needed to account for the
cases where you either supplied a symbol (that stood for the name of
the object) or a symbol and the object (as an instance variable). Of
course I ripped all that off by studying the Rails form_for. :slight_smile:

On 21 May 2008, at 11:25, Greg W. wrote:

Just to see if @object exists, I used debug(@object) right inside
there though).

<% form_for :edp_target,
:url => {:action => :record_editor},
:builder => EdpBuilder do |form| %>

<%= debug() %>

where () = (@object), (form.object), or (object) – none yield any
data.

Reading the source, it appears that form_for :edp_target, @edp_target
will populate object properly with @edp_target (and with 2.0, just
form_for @edp_target would work)

Fred