Question regarding symbols

I asked in #rubyonrails on freenode, but unfortunately, am either
clueless
to the explanation technoweenie gave about using a block, or he didn’t
understand my problem.

I have a site in the works, based on nested controllers and rest.

eg: /clients/1/foo/2/bar/3

The problem, is in the controller foo, i have to have:

before_filter :load_client

In bar,

before_filter :load_foo

The issue is when i have a large app, I don’t want to have 50 versions
of
the load_* when all they do is set @key =
Something.findparams[:something_id]

So, my question, how would I be able to create a method named
load_parent
and do:

before_filter :load_parent :client

Then have load_parent take :symbol and do @(symbol.to_s) =
symbl.to_s.findparams[:symbol_id]

Hopefully this makes sense.

Thanks.

Hi –

On Sat, 3 Feb 2007, kris wrote:

before_filter :load_client

before_filter :load_parent :client

Don’t forget the comma between arguments in method calls :slight_smile:

Then have load_parent take :symbol and do @(symbol.to_s) =
symbl.to_s.findparams[:symbol_id]

Hopefully this makes sense.

I didn’t see Rick’s suggestion, so I don’t know whether this is
similar, but here’s one possibility. (If you don’t understand it,
there’s a book I can recommend that serves the specific purpose of
explaining Ruby in depth to Rails developers :slight_smile:

First, in application.rb (the parent controller file), write your
load_param (or parent, but I think param makes more sense) method. In
fact, make it plural, so that you can handle more than one symbol at a
time:

def load_params(*symbols)
symbols.each do |sym|
c = Object.const_get(Inflector.classify(sym))
instance_variable_set(“@#{sym}”, c.find(params[“#{sym}_id”]))
end
end

That method uses the utility object Inflector to get the class-like
version of sym (:x becomes “X”, :some_thing becomes “SomeThing”,
etc.). That string can then be used by Object.const_get to get the
actual class object.

The next line does the actual setting of the instance variable.

Now, in the controller where you want this to happen, you can do:

before_filter {|c| c.load_params(:a,:b,:c) }

When you give a code block to before_filter, the controller object
itself gets yielded to the block; that’s c. So you can then call
load_param on c, passing in the params you want to set.

There are other ways to engineer this, but that’s one way that gives
you a pretty high-level interface in the controller itself.

David


Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (Ruby for Rails)
(See what readers are saying! http://www.rubypal.com/r4rrevs.pdf)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)

Hi –

On Sun, 4 Feb 2007, kris wrote:

David,

Thanks for the help. It didn’t seem to be working, I was getting:

`@{sym}’ is not allowed as an instance variable name

You need:

“@#{sym}”

Here’s my example again:

def load_params(*symbols)
symbols.each do |sym|
c = Object.const_get(Inflector.classify(sym))
instance_variable_set(“@#{sym}”, c.find(params[“#{sym}_id”]))
end
end

You don’t have to do any to_s; string interpolation does that
automatically.

David


Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (Ruby for Rails)
(See what readers are saying! http://www.rubypal.com/r4rrevs.pdf)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)

I feel like an idiot. Thanks :slight_smile:

David,

Thanks for the help. It didn’t seem to be working, I was getting:

`@{sym}’ is not allowed as an instance variable name

I realized I had to convert the symbol to a string first, also, {} isn’t
allowed in the variable name (it’s not being interpolated?), thus, my
solution (which works great).

instance_variable_set(’@’ + sym.to_s, c.find(params["#{sym}_id"]))

replace that line and it’s great :smiley:

Thanks for the help, much appreciated.