Forum: Ruby on Rails Including another helper

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
marcus (Guest)
on 2006-02-12 11:40
(Received via mailing list)
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. (Guest)
on 2006-02-12 18:15
(Received via mailing list)
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.
removed_email_address@domain.invalid

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
marcus (Guest)
on 2006-02-12 21:12
(Received via mailing list)
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
James L. (Guest)
on 2006-02-12 21:26
(Received via mailing list)
On 2/12/06, marcus <removed_email_address@domain.invalid> 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
marcus (Guest)
on 2006-02-12 22:32
(Received via mailing list)
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 :( ).

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
Justin F. (Guest)
on 2006-02-14 16:13
(Received via mailing list)
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?

   http://en.wikipedia.org/wiki/Visitor_pattern

regards

   Justin
Seth R. (Guest)
on 2006-03-22 08:57
(Received via mailing list)
On 2/12/06, marcus <removed_email_address@domain.invalid> 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/
This topic is locked and can not be replied to.