I have an observer which looks like this:
class CommentObserver < ActiveRecord::Observer
    include ActionView::Helpers::UrlHelper
    def after_create(comment)
        message = "#{link_to comment.user.full_name, user_path(comment.user)} commented on #{link_to 'your photo',photo_path(comment.photo)} of #{comment.photo.location(:min)}"
        Notification.create(:user=>comment.photo.user,:message=>message)
    end
end
Basically all I'm using it to do is create a simple notification message for a certain user when someone posts a comment on one of their photos.
This fails with an error message:
NoMethodError (undefined method `link_to' for #<CommentObserver:0x00000102fe9810>):
I would have expected including ActionView::Helpers::UrlHelper would solve that, but it seems to have no effect.
So, how can I include the URL helper in my observer, or else render this some other way? I would happily move the "message view" into a partial or something, but an observer has no associated views to move this to...
Why aren't you building the message when it's rendered out to the page and then caching it using something like this?
<% cache do %>
  <%= render user.notifications %>
<% end %>
This would save you having to do a hack in the observer and would be more "standards compliant" in Rails.
To handle this type of thing, I made an AbstractController to generate the body of the email, then I pass that in as a variable to the mailer class:
  class AbstractEmailController < AbstractController::Base
    include AbstractController::Rendering
    include AbstractController::Layouts
    include AbstractController::Helpers
    include AbstractController::Translation
    include AbstractController::AssetPaths
    include Rails.application.routes.url_helpers
    include ActionView::Helpers::AssetTagHelper
    # Uncomment if you want to use helpers 
    # defined in ApplicationHelper in your views
    # helper ApplicationHelper
    # Make sure your controller can find views
    self.view_paths = "app/views"
    self.assets_dir = '/app/public'
    # You can define custom helper methods to be used in views here
    # helper_method :current_admin
    # def current_admin; nil; end
    # for the requester to know that the acceptance email was sent
    def generate_comment_notification(comment, host = ENV['RAILS_SERVER'])
        render :partial => "photos/comment_notification", :locals => { :comment => comment, :host => host }
    end
  end
In my observer:
  def after_create(comment)
     email_body = AbstractEmailController.new.generate_comment_notification(comment)
     MyMailer.new(comment.id, email_body)
  end
                        So, it turns out this cannot be done for the same reason you can't use link_to in a mailer view. The observer has no information about the current request, and therefore cannot use the link helpers. You have to do it a different way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With