I was looking at my controller code and the edit/create/update/new for
each are practically identical. So first I DRY''d the four methods in
each controller to just one and then I decided to write a single macro
for all my controllers.
This is the macro:
def self.edit_action_for(model, options = {})
model_class = Object.const_get(model)
define_method(:edit) do
edit_code = lambda do
@thing = model_class.find_by_id(params[:id]) || model_class.new
if request.post?
@thing.attributes = params[:impactable_area]
if @thing.save
flash[:notice] = "#{model.humanize} successfully saved."
redirect_to :action => ''list''
end
end
end
end
end
Then I expected this
edit_action_for :ImpactableArea
to create my "edit" method.
Problem is that it doesn''t :-(
So then I looked to see how I could do a macro expansion (as you can in
Lisp) to see what''s being produced and I couldn''t find
anything...
HELP!
Edward
--
Posted via http://www.ruby-forum.com/.
The problem is that you''re not actually adding a new method definition
to the class when you call "edit_action_for" - you''re just
calling a
class method. Basically you''re doing this:
class Blah
def self.test
# do something
# return something maybe?
return ''hello!'' # in this case
end
# now call this
test
end
==> ''hello!''
... not what you want. In your abstracted-out class method, you
actually want to be creating a new method to be added to the class
definition in which your macro is being called. You probably want to
investigate the delightful intricacies of define_method and
eval/class_eval - welcome to metaprogamming...
- james
On 6/8/06, Edward Kenworthy <edward@kenworthy.info>
wrote:> I was looking at my controller code and the edit/create/update/new for
> each are practically identical. So first I DRY''d the four methods
in
> each controller to just one and then I decided to write a single macro
> for all my controllers.
>
> This is the macro:
>
> def self.edit_action_for(model, options = {})
> model_class = Object.const_get(model)
> define_method(:edit) do
> edit_code = lambda do
> @thing = model_class.find_by_id(params[:id]) || model_class.new
> if request.post?
> @thing.attributes = params[:impactable_area]
> if @thing.save
> flash[:notice] = "#{model.humanize} successfully
saved."
> redirect_to :action => ''list''
> end
> end
> end
> end
> end
>
> Then I expected this
>
> edit_action_for :ImpactableArea
>
> to create my "edit" method.
>
> Problem is that it doesn''t :-(
>
> So then I looked to see how I could do a macro expansion (as you can in
> Lisp) to see what''s being produced and I couldn''t find
anything...
>
> HELP!
>
> Edward
>
> --
> Posted via http://www.ruby-forum.com/.
> _______________________________________________
> Rails mailing list
> Rails@lists.rubyonrails.org
> http://lists.rubyonrails.org/mailman/listinfo/rails
>
--
* J *
~
James Adam wrote:> <snip> > ... not what you want. In your abstracted-out class method, you > actually want to be creating a new method to be added to the class > definition in which your macro is being called. You probably want to > investigate the delightful intricacies of define_method and > eval/class_eval - welcome to metaprogamming... > > - jamesThink you may have misread my code. Have a look at Line 2 of edit_action_for define_method(:edit) do Edward -- Posted via http://www.ruby-forum.com/.
You''re absolutely right. Hopefully this will help me pay penance for
my illiteracy:
class Blah
def self.new_thing(arg)
define_method(:do_it!) do
puts "ok: #{arg}"
end
end
new_thing "monkey"
end
b = Blah.new
b.do_it!
# ==> ok: monkey
module Mung
def self.new_thing(arg)
define_method(:do_it!) do
puts "ok: #{arg}"
end
end
end
class Jazz
include Mung
new_thing "baboon"
end
j = Jazz.new
j.do_it!
# ==> undefined method `new_thing'' for Jazz:Class (NoMethodError)
module Soul
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def new_thing(arg)
define_method(:do_it!) do
puts "Hit it; #{arg}"
end
end
end
end
class Funk
include Soul
new_thing "Watch me now!"
end
f = Funk.new
f.do_it!
# ==> Hit it; Watch me now!
- james
On 6/8/06, Edward Kenworthy <edward@kenworthy.info>
wrote:> James Adam wrote:
> > <snip>
> > ... not what you want. In your abstracted-out class method, you
> > actually want to be creating a new method to be added to the class
> > definition in which your macro is being called. You probably want to
> > investigate the delightful intricacies of define_method and
> > eval/class_eval - welcome to metaprogamming...
> >
> > - james
>
> Think you may have misread my code. Have a look at Line 2 of
> edit_action_for
>
> define_method(:edit) do
>
> Edward
>
>
> --
> Posted via http://www.ruby-forum.com/.
> _______________________________________________
> Rails mailing list
> Rails@lists.rubyonrails.org
> http://lists.rubyonrails.org/mailman/listinfo/rails
>
--
* J *
~