Using helpers from controllers?

There is a solution to use helpers from controllers ?

I have an error :

|undefined method `content_tag’|

class ApplicationController < ActionController::Base

def test
return content_tag(“a”,“test”)
end

end

the short answer is:

you should never ever need it or do it

helpers are supposed to be used inside views, not controllers

So, if I need to create a class who use a helper, I need to create my
class inside application_helper.rb, not inside application.rb ?

On Mar 4, 2006, at 11:16, Peter E. wrote:

the short answer is:

you should never ever need it or do it

helpers are supposed to be used inside views, not controllers

I found a use case this week that I think justifies the usage of a
helper in a controller.

Employees in my application are displayed using a helper, there’s a
html flag to set to false if the employee name goes into something
like a combo:

def display_employee(e, html=true)
out = ‘’
if html
out << h("#{e.surname}, #{e.first_name}")
out << ‘ν’ if e.is_virtual?
else
out << “#{e.surname}, #{e.first_name}”
out << " (v)" if e.is_virtual?
end
out
end

Right, now the requirement is for the controller to generate a CSV
file that contains employee names among other data. The CSV has no
template, it is built on the fly with stringio.rb. In my view it
makes sense to leverage that helper following DRY.

– fxn

PD: In order to accomplish that I just included the helper module:

 class MyController ...
   include MyHelper

try using a builder template.

On Mar 4, 2006, at 12:17, Peter E. wrote:

try using a builder template.

I don’t understand how. That feature needs stringio.rb and csv.rb,
where is the XML?

– fxn

If I include TagHelper I have always the error

|undefined method `content_tag’

How include the TagHelper to use content_tag ?
|

class Test
include ApplicationHelper
include TagHelper

def aaa
content_tag(“p”,“jojo”)
end
end

On Mar 4, 2006, at 13:21, Luke R. wrote:

the controller then use a normal RHTML view to construct your CSV
structure. You can even set the content disposition to ensure that the
CSV view is always prompted for download, never displayed.

In my understanding a CSV is not a “view”, in my application is a
“file” to download, and that’s the actual usage except for the fact
that there’s no real file being served. Not every response is a view
unless you force the MVC metaphor.

I feel the natural way to send a CSV file is just to build it (or
load it) in the controller and delegate to send_data(). Isn’t that
the purpose of send_data()?

I’m not sure why you’d need to use something like StringIO, couldn’t
you just loop over your records to get each row, and over each field
to get each column, separated by commas?

Building a CSV file is not the same as join(","). That’s why I
delegate to the standard library csv.rb, which deals with IO-like
objects.

– fxn

Xavier your use case still doesn’t present a convincing argument for
using helpers in the controller. Rails helpers are based on a pattern
known as the ViewHelper which should indicate where they should be
used.

In the use case you present, your CSV output IS the view despite the
fact you are generating it in your controller. In fact, you should be
generating a view for it.

The first way of approaching this would be to set the content type in
the controller then use a normal RHTML view to construct your CSV
structure. You can even set the content disposition to ensure that the
CSV view is always prompted for download, never displayed.

I’m not sure why you’d need to use something like StringIO, couldn’t
you just loop over your records to get each row, and over each field
to get each column, separated by commas?

On 3/4/06, oo00oo [email protected] wrote:

include TagHelper



Cheers,
Luke R.

In my understanding a CSV is not a “view”

It actually is a view - a view is a presentation of your data. Whether
that be HTML, XML, PDF, CSV or anything else, it is a view. Whether
that data is displayed in the browser or pushed to the user as a
download, its still a view.

Not every response is a view unless you force the MVC metaphor.

Well, there are two typical responses in an MVC app - the controller
either redirects somewhere else, or presents a view.

Building a CSV file is not the same as join(",").

Surely a CSV file is just rows of records, with fields separated by
commas? Whats wrong with this in an RHTML view (with content-type set
in the controller):

<% @people.each do |person| %>
<% person.name %>, <% person.age %>, <% person.gender %>
<% end %>

A simple, CSV presentation of people from my database. You can wrap
the behaviour up even more by creating a CSVHelper that takes a
collection and an array of fields you want to present which wraps
things up even more elegantly. But its still a view. If you want to
send the view to the end user as a downloadable file, then Rails makes
that easy enough. In your controller:

def people_csv_download
@headers[“Content-Type”] = ‘text/csv’
@headers[“Content-Disposition”] = ‘attachment’
end

xml, csv, are all presentations of data

the data itself is considered to be objects and variables in ruby

Building a CSV file is not the same as join(",").

why not? results are similar…

On Mar 4, 2006, at 14:21, Luke R. wrote:

In my understanding a CSV is not a “view”

It actually is a view - a view is a presentation of your data. Whether
that be HTML, XML, PDF, CSV or anything else, it is a view. Whether
that data is displayed in the browser or pushed to the user as a
download, its still a view.

From a high-level point of view we certainly agree.

But you still suggest to use RHTML, that kind of makes sense because
CSV sounds plain text and doable with RHTML. But this is where the
metaphor is not being applied in the right way in my opinion.

I find more natural to serve a download with plain send_data(). The
controller uses as “view” generator zlib.rb, RMagick, the filesystem,
whatever appropriate, not a templating system! And then it calls
send_data(). The render() in that controller is the call to zlib.rb,
RMagick, or the filesystem. Is done before the action returns. But
the pattern is still respected in my view.

But I see your point, if I had factored out the generation of the CSV
in a view-like component of some sort I wouldn’t have included
ApplicationHelper in the controller which is actually suspicious.
Yeah, right.

Not every response is a view unless you force the MVC metaphor.

Well, there are two typical responses in an MVC app - the controller
either redirects somewhere else, or presents a view.

Building a CSV file is not the same as join(",").

Surely a CSV file is just rows of records, with fields separated by
commas?

There are extra conventions about separators, quotes, separators
within fields, etc. That’s why csv.rb is the way to go, delegate in a
module that knows the format and go have lunch earlier :-).

– fxn

Xavier,

I am in agreement with you here. I do the same thing with csv data. I
use
the csv library within my controller to generate the data and use
send_data. there is no template in this case.

But I have another situation where I generate excel data via an rxml
builder
template. in this case, i load the records and set the header in the
controller then let the template construct the xml data.

so it definitely depends on the situation.

Chris

Xavier, whilst I see your points for creating CSV files using an
existing library, generating a view is still not the job of a
controller. The controller should delegate to an appropriate view
rendering object that knows how to render itself. In Rails case, that
is an RHTML or RXML view. But thats just what comes out of the box.

It seems to me, if you don’t want to use RHTML, then the real answer
here is to create your own template format, rcsv for example, that
lets you write CSV templates.

I still think the easiest solution, and the one that maintains true
controller/view separation, is to simply use RHTML.

On 3/4/06, Chris H. [email protected] wrote:

so it definitely depends on the situation.

that be HTML, XML, PDF, CSV or anything else, it is a view. Whether
controller uses as “view” generator zlib.rb, RMagick, the filesystem,

Not every response is a view unless you force the MVC metaphor.
within fields, etc. That’s why csv.rb is the way to go, delegate in a


Rails mailing list
[email protected]
http://lists.rubyonrails.org/mailman/listinfo/rails


Cheers,
Luke R.