Link_to/url_for in an "model" object quandry

OK, I’ve googled and found some discussion about this and seen the
scolding about breaking the MVC pattern as in “why do you need to do
that?”, but I do have a situation where it makes some sense. Let me
describe…

I have a new service called redeyestats.com and the major function is
to send a daily email with a report (specifically a daily stats
listing for sports players that the user is following). This report
mirrors a page with the same info on the site.

I want to keep things DRY, so it seemed like a good idea to create a
Reporter class that would compile each player report for both cases of
a) compiling the email and b) the site’s page listing. Each player
report has links in it to the player’s page, their team page, and to a
game page for their latest game.

So, I do have a need to build links within this reporter object. It’s
not a model object in the sense of MVC, but it’s not a controller or a
view and , so, it doesn’t resolve the named routes.

I’m open to suggestions for another approach that will work for both
of my use cases… or for a way to make this work as designed.

Does anyone have suggestions on how to make this work? Thx

On Tue, 3 Mar 2009 20:56:47 -0800 (PST)
lunaclaire [email protected] wrote:

I have a new service called redeyestats.com and the major function is
to send a daily email with a report (specifically a daily stats
listing for sports players that the user is following). This report
mirrors a page with the same info on the site.

I want to keep things DRY, so it seemed like a good idea to create a
Reporter class that would compile each player report for both cases of
a) compiling the email and b) the site’s page listing. Each player
report has links in it to the player’s page, their team page, and to a
game page for their latest game.

This sounds like a pretty straightforward use case for ActionMailer. You
can add links to your email via actionmailer templates (via link_to).
Then you can use the regular controller/view mechanism for your pages.

So in summary

  1. Store all of your player data in the model
  2. Use an actionmailer template for the email
  3. Use normal views for the pages

SH

Starr H.
My blog: http://starrhorne.com
Check out my Helpdesk RailsKit: http://railskits.com/helpdesk/

It does seem like it should be straightforward, but there’s a bunch of
complex logic that I dont want to put directly into views. Initially I
had it in a helper, then pulled it into the Reporter object I
mentioned, but then I got the problem I mentioned.

My latest has the logic in a Module. What I find interesting is that
when called from the views (pages), it works fine; but when called
from the mailer, I get the following:

undefined method `player_url’ for ReportHelper:Module

Here’s some of the code in the module:

module ReportHelper

include ActionView::Helpers::UrlHelper
include ActionController::UrlWriter
include ActionView::Helpers::TagHelper

def self.html_tracker_report(player, stat, updates, last_update,
for_email=false)
output = []
spacer = "   "

if for_email
  line = '<span style="font-weight: bold;">' + link_to(player.name,

player_url(player), :style => “color: #666; font-weight:bold; text-
decoration: none;”) + ‘’ + spacer
else
line = ‘’ + link_to(player.name,
player_path(player)) +’
’ + spacer
end
end

Note the includes and note the logic (“if for_email”) that is set up
to separately deal with CSS issues in the email. It’s slightly
different where the email part uses player_url vs player_path, but
I’ve tried both and still see problems in resolving the named route.

One more detail that might give a clue: The emails are generated from
a rake task (invoked by a cron job) rather than from some use action
on the site. I dont think that makes a difference, but, maybe…?

My guess is that I haven’t included something… or maybe I’m not
calling link_to correctly for this case. But, I dont see it so any
help is appreciated.

Thx again, Starr.

The thing is, I already have the line:

include ActionController::UrlWriter

in the module. And get the error.

And I don’t think I can just put the ‘default_url_options’ line in
there…isn’t that an ActionMailer options hash?

Or am I missing it completely as to where to put these lines?

On Mar 4, 2:26 pm, lunaclaire [email protected] wrote:

Or am I missing it completely as to where to put these lines?

I’m not clear why you’re trying to do this formatting in a helper -
isn’t this a task better suited for a partial? The typical Rails idiom
would be to have methods in the model that return the objects you’re
interested in (in this case, players and however you’re representing
updates), while the view code takes care of producing the actual
output.

Note that the “no logic in views” rule is more like a guideline - not
a reason to insist on lobotomized views. If there’s logic that solely
concerns views (ie show/hide things based on state, user
authorization, etc), it belongs in the view.

–Matt J.

OK, thank you all for getting my head straightened out.

I refactored and dumped the Reporter object and the ReportHelper
module and went back to having all the needed code in
ApplicationHelper. I liked the idea of encapsulating the entire
report in an object to produce it and then rendering it line by line
in the email, but this works.

I guess everything just needs to be kept in its place. :slight_smile:

Thx again and sorry for the noise.

One more detail that might give a clue: The emails are generated from
a rake task (invoked by a cron job) rather than from some use action
on the site. I dont think that makes a difference, but, maybe…?

Named routes aren’t accessible by default in the console, and I imagine
they aren’t in your rake task, either.

Here’s instructions on how to include them:


Starr H.
My blog: http://starrhorne.com
Check out my Helpdesk RailsKit: http://railskits.com/helpdesk/