Rails: используйте URL Helper в Observer
У меня есть наблюдатель, который выглядит так:
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
По сути, все, что я использую для этого, - это создание простого уведомления для определенного пользователя, когда кто-то публикует комментарий на одной из его фотографий.
Это терпит неудачу с сообщением об ошибке:
NoMethodError (undefined method `link_to' for #<CommentObserver:0x00000102fe9810>):
Я бы ожидал, в том числе ActionView::Helpers::UrlHelper
решил бы это, но это, кажется, не имеет никакого эффекта.
Итак, как я могу включить помощника URL в моем обозревателе, или иначе сделать это другим способом? Я бы с радостью переместил "представление сообщения" в частичное или что-то еще, но у наблюдателя нет связанных представлений, чтобы переместить это в...
3 ответа
Таким образом, оказывается, что это не может быть сделано по той же причине, по которой вы не можете использовать link_to
в почтовом представлении. У наблюдателя нет информации о текущем запросе, и поэтому он не может использовать помощников по ссылкам. Вы должны сделать это по-другому.
Чтобы справиться с этим, я создал AbstractController для генерации тела письма, а затем передал его в качестве переменной в класс почтовика:
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
По моему наблюдателю:
def after_create(comment)
email_body = AbstractEmailController.new.generate_comment_notification(comment)
MyMailer.new(comment.id, email_body)
end
Почему вы не создаете сообщение, когда оно выводится на страницу, а затем кэшируете его, используя что-то вроде этого?
<% cache do %>
<%= render user.notifications %>
<% end %>
Это избавит вас от необходимости взламывать обозреватель и будет более "соответствовать стандартам" в Rails.