Help with "generating" code

Hello,

OK, this is a Ruby question, even though it’s for a RoR project :smiley:
I am a pretty hopeless Ruby programmer. I am getting better, but when
it’s about eval(), symbols and introspection, I still crumble…
Besides, I am not even sure what I want to do is actually possible in
Ruby.

At one point, in my program I have this:

def create
@channel = Channel.new(params[:channel])
if @channel.save
flash[:notice] = ‘Channel was successfully created.’
redirect_to :action => ‘index’
else
render :action => ‘new’
end
end

What I want to do, is being able to write:

def create
ApplicationController::standard_create(:channel)
end

That “standard_create” function should execute the code, but in
create()'s scope.
What I don’t know is:

  1. How to keep the code execute by
    ApplicationController::standard_create in create()'s scope
  2. From ApplicationController::standard_create(name), what to do to
    “create the code”

Any help would be immensely appreciated!

Thanks a lot,

Merc.

Merc,

You could add a method to Channel that looks like:
class Channel
def self.standard_create(params, controller)
ret = Channel.new params
if ret.save
controller.flash[:notice] = ‘Channel was saved’
controller.redirect_to :action => ‘index’
else
controller.render :action => ‘new’
end
return ret
end
end

No need for metaprogramming in this case, just a simple method.

Thanks,

David

Lightly tested:

class Parent
def self.standard_create(name)
upper_name = name.to_s.capitalize
klass = Kernel::const_get upper_name
define_method(:create) do
ret = instance_variable_set("@#{name}", klass.new(params[name]))
if ret.save
flash[:notice] = “#{upper_name} successfully created.”
redirect_to :action => ‘index’
else
render :action => ‘new’
end
end
end

def flash() (@flash||={}) end
def params() (@params||={}) end
def redirect_to(what) puts “Redirecting to #{what[:action]}” end
def render(hash) puts “Rendering #{hash[:action]}” end

end

Test2 = Struct.new :params
class Test2
def save
puts “Saving with #{params}”
end
end

Only the standard_create method is important, the result is just fluff
to emulate some of Rails and show its usage.

Hi,

THANK YOU

I ended up using a solution that was a little different to what I
originally thought of. However, your input was vital for me. The main
problem was that I was trying to write a class method, where an instance
method was probably a better idea.
Let me show what I did. I know this is RoR code. However, what I am
focusing on is Ruby code here.
So, here is what I did.
In the application controller:

class Lookup::AccountNumberController < ApplicationController
[…]

def create
standard_create :account_number
end
[…]

Then, in the ApplicationController the real magic happens:

class ApplicationController < ActionController::Base
[…]

def standard_create(name)

# Fetch the class's pointer called "Name" - THANK YOU Ruby ML!
klass = self.class::const_get(Inflector.classify(name.to_s))

# Set @name. For example:
# @channel = Channel.new(params[:channel]) -  - THANK YOU Ruby ML!
variable=instance_variable_set('@'+name.to_s,klass.new(params[name]) 

)

# Try and save the object, blah blah
if variable.save
  flash[:notice] = "#{name.to_s.humanize} was successfully created."
  redirect_to :action => 'index' if ! parent
else
  render :action => 'new'
end

end
[…]
end

The big issue is that I needed to assign an instance variable, but all I
had was the name. So,
instance_variable_set(’@’+name.to_s,klass.new(params[name]) ) really
did the trick. Also, it took me a while to get klass =
self.class::const_get(Inflector.classify(name.to_s)) (OK, it probably
sounds totally obvious to you…).

That
variable=instance_variable_set(’@’+name.to_s,klass.new(params[name]) )
is a bit of an eye sore. I wonder if there’s a better way of “pointing”
to the instance variable directly…?

Anyway… Ruby truly is beautiful. In my application, I have LOADS and
LOADS of tables that are ridicolously similar. Well, this techniques
literally saves me from cutting&pasting the same code over and over
again.

I will probably end up writing an article about this (when I am more
comfortable with what I’m doing).

Bye!

Merc.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs