Including another helper

I need to include another helper module apart from the normal two
(ApplicationHelper and [controllername]Helper). The inclusion needs to
be dynamic and based on external parameters (ie what helper that get
included differ from request to request).

Is it possible? How?

/Marcus

In your controller, after your class declaration

helper :modelname

Although if you’re goign to have things that exist across multiple
models and controllers, wouldn’t it make more sense to extrapolate
those up to a higher level?

On Feb 12, 2006, at 4:39 AM, marcus wrote:

I need to include another helper module apart from the normal two
(ApplicationHelper and [controllername]Helper). The inclusion needs
to be dynamic and based on external parameters (ie what helper that
get included differ from request to request).

Is it possible? How?

/Marcus

John A.
[email protected]

Meticulous | www.meticulous.com (work)
Rotoscope | www.rotoscope.com (sound: rock band)
Boboroshi & Kynz | www.boboroshiandkynz.com (sound: electronic)
Personal Weblog | www.boboroshi.com (play)

“Those who would give up essential Liberty, to purchase a little
temporary Safety, deserve neither Liberty nor Safety.”
- Benjamin Franklin (1706-1790)
Reply of the Pennsylvania Assembly to the
Governor
November 11, 1755

John A. skrev:

In your controller, after your class declaration

helper :modelname

Although if you’re goign to have things that exist across multiple
models and controllers, wouldn’t it make more sense to extrapolate
those
up to a higher level?

The problem I have is that I need “polymorphic” helpers and what
helper(s) to use is request based (both parameters and database data).
Your approach and the other one you propose is kind of static and I
can’t override on a request by request basis (or it’ll probably be on an
invocation by invocation basis of render_to_string() even).

Although I think I can probably come up with something now that I see
your proposal. But if someone can give me a hint of something to use
inside a method then I’ll be very happy…

/Marcus

On 2/12/06, marcus [email protected] wrote:

helper(s) to use is request based (both parameters and database data).
Your approach and the other one you propose is kind of static and I
can’t override on a request by request basis (or it’ll probably be on an
invocation by invocation basis of render_to_string() even).

Although I think I can probably come up with something now that I see
your proposal. But if someone can give me a hint of something to use
inside a method then I’ll be very happy…

Can you give a little more detail of what you’re trying to do, and
maybe more importantly why you think you need to do it?

From the details given so far, I’m thinking that there’s a design flaw
in here somewhere.

– James

James L. skrev:

Can you give a little more detail of what you’re trying to do, and
maybe more importantly why you think you need to do it?

Ok. It’s yet another CM tool…

I have a tree of nodes (STI model using composition that references the
actual content models) with different node types representing pages
(which in turn is a collection of content items), folders, sites,
templates, images, links etc… Each node type is responsible of
rendering themselves to files at publish (when publish is “static”, ie
published to a server not supporting rails :frowning: ).

So what I want to do is create a publish method in my NodesController
that simply calls publish() on the node in question without actually
having a clue about the node type (polymorphism in action). Some of the
nodes are pretty simple (images just goes straight into a file, a link
doesn’t get rendered at all since they are statically imported into the
page that uses them) but pages for example are more complex since the
templates relies on ERB. Other types, such as sites and folders, may
just control flow rather than producing files. If I create other node
types that also relies on ERB I want a generic way of handling this (the
node type creator shouldn’t have to fiddle with the NodesController).
Each of these node types may have a helper associated and in that case I
need to associate it with the current “scope”.

I can now invoke ERB through render_to_string() by passing a closure
from the controller into the models so they themselves can decide if
they want to use render_to_string() or not

Something like this:

def publish
Node.find(params[:id]).publish { |template, vars|
vars.each_key { |key|
self.instance_eval("@#{key} = vars[key]")
}
render_to_string :inline => template
}
render :text => “published node #{params[:id]}”
end

PageNode < Node

def publish
File.open(publish_path, “wb”) do |file|
#uses the “publish” block passed in
result = yield(page.page_template.content,
:view_mode => “show”,
:page_node => self,
:page => page,
:view_node => self)
file.write(result)
end
end

end

ImageNode < Node

def publish
#doesn’t care about the block passed in, just prints the data
File.open(publish_path, “wb”) { |file| file.print image.data }
end

end

What I would like is to somehow pass the helpers together with the other
params I pass into the block.

The point with doing all of this is that when adding a new node type I
only have to deal with the actual node type, not with all surrounding
framework code. I have one place to change/add things when I want to
change a node type, not several places where other might also be
affected (trying to keep it orthogonal)

Can you give a little more detail of what you’re trying to do, and
maybe more importantly why you think you need to do it?

Well, it might me something like that, I don’t know. I just want to keep
it modularized and having as few concerns in each place as possible. The
main problem is the requirement to publish to static files (doesn’t fit
very well with Rails itself maybe). I tried to use open-uri and call
nodes/show/[my_id] and just put that in a file but Webrick seemed to
deadlock or something (does it only support one request at a time??)

It would be fun to hear some feedback on the design as well though,
maybe you have some input for something simpler that I completely
missed.

/Marcus

On 2/12/06, marcus [email protected] wrote:

I need to include another helper module apart from the normal two
(ApplicationHelper and [controllername]Helper). The inclusion needs to
be dynamic and based on external parameters (ie what helper that get
included differ from request to request).

Is it possible? How?

Filters. The request based requirement seems to make your controller a
no-brainer. The controller then conditionally adds new instance
methods to the appropriate objects.

Seems sound.


Seth Thomas R.
http://sethrasmussen.com/

marcus wrote:

nodes are pretty simple (images just goes straight into a file, a link
from the controller into the models so they themselves can decide if
}
:page_node => self,
def publish
only have to deal with the actual node type, not with all surrounding
very well with Rails itself maybe). I tried to use open-uri and call
nodes/show/[my_id] and just put that in a file but Webrick seemed to
deadlock or something (does it only support one request at a time??)

Rails, by default, only handles one request at a time. In FCGI and SCGI
environments this translates to one request per FCGI/SCGI process at a
time.

It would be fun to hear some feedback on the design as well though,
maybe you have some input for something simpler that I completely missed.

It sounds as if you should be passing an object around, encapsulating
any helpers required and any stream to which output is being done.
Then you could choose which class to instantiate for this purpose
according to the request being handled.

Are you familiar with the Visitor pattern?

Visitor pattern - Wikipedia

regards

Justin