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> --- Urspr?ngliche Nachricht --- > Von: oo00oo <oo00oo@free.fr> > An: rails@lists.rubyonrails.org > Betreff: [Rails] Using helpers from controllers ? > Datum: Sat, 04 Mar 2006 11:12:45 +0100 > > 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 > > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
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 ?> the short answer is: > > you should never ever need it or do it > > helpers are supposed to be used inside views, not controllers > >
On Mar 4, 2006, at 11:16, Peter Ertl wrote:> the short answer is: > > you should never ever need it or do it > > helpers are supposed to be used inside views, not controllersI 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 << ''<sup>ν</sup>'' 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.> --- Urspr?ngliche Nachricht --- > Von: Xavier Noria <fxn@hashref.com> > An: rails@lists.rubyonrails.org > Betreff: Re: [Rails] Using helpers from controllers ? > Datum: Sat, 4 Mar 2006 12:02:54 +0100 > > On Mar 4, 2006, at 11:16, Peter Ertl 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 << ''<sup>ν</sup>'' 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 > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
On Mar 4, 2006, at 12:17, Peter Ertl 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> > > class MyController ... > include MyHelper > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails > >
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 <oo00oo@free.fr> wrote:> 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 > > > > > > > class MyController ... > > include MyHelper > > _______________________________________________ > > Rails mailing list > > Rails@lists.rubyonrails.org > > http://lists.rubyonrails.org/mailman/listinfo/rails > > > > > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- Cheers, Luke Redpath www.lukeredpath.co.uk
On Mar 4, 2006, at 13:21, Luke Redpath wrote:> 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.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
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...> --- Urspr?ngliche Nachricht --- > Von: Xavier Noria <fxn@hashref.com> > An: rails@lists.rubyonrails.org > Betreff: Re: [Rails] Using helpers from controllers ? > Datum: Sat, 4 Mar 2006 13:36:29 +0100 > > On Mar 4, 2006, at 13:21, Luke Redpath wrote: > > > 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. > > 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 > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
>> 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
On Mar 4, 2006, at 14:21, Luke Redpath 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 On 3/4/06, Xavier Noria <fxn@hashref.com> wrote:> > On Mar 4, 2006, at 14:21, Luke Redpath 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 > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060304/ee0cb805/attachment.html
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 Hall <christopher.k.hall@gmail.com> wrote:> 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 > > > On 3/4/06, Xavier Noria <fxn@hashref.com> wrote: > > On Mar 4, 2006, at 14:21, Luke Redpath 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 > > > > _______________________________________________ > > Rails mailing list > > Rails@lists.rubyonrails.org > > http://lists.rubyonrails.org/mailman/listinfo/rails > > > > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails > > >-- Cheers, Luke Redpath www.lukeredpath.co.uk