la bonne solution
Eh bien, "ils" sont à droite. Vous avez vraiment à faire le rendu dans un contrôleur
mais c'est le jeu juste à appeler le contrôleur à partir d'un modèle! Heureusement, AbstractController
dans Rails 3, il est plus facile que je ne le pensais. J'ai fini par faire un simple
ActionPusher de classe, de travail tout comme ActionMailer. Peut-être que je vais obtenir ambitieux et
faire de cette un bon bijou un jour, mais cela devrait servir comme un bon début pour quelqu'un d'autre dans mes chaussures.
J'ai eu le plus de l'aide de ce lien: http://www.amberbit.com/blog/2011/12/27/render-views-and-partials-outside-controllers-in-rails-3/
dans lib/action_pusher.rb
class ActionPusher < AbstractController::Base
include AbstractController::Rendering
include AbstractController::Helpers
include AbstractController::Translation
include AbstractController::AssetPaths
include Rails.application.routes.url_helpers
helper ApplicationHelper
self.view_paths = "app/views"
class Pushable
def initialize(channel, pushtext)
@channel = channel
@pushtext = pushtext
end
def push
Pusher[@channel].trigger('rjs_push', @pushtext )
end
end
end
dans app/poussoirs/users_pusher.rb. Je suppose que le besoin pourrait aller quelque part plus global?
require 'action_pusher'
class UsersPusher < ActionPusher
def initialize(user)
@user = user
end
def channel
@user.pusher_key
end
def add_notice(notice = nil)
@notice = notice
Pushable.new channel, render(template: 'users_pusher/add_notice')
end
end
Maintenant, dans mon modèle, je peux faire ça:
after_commit :push_add_notice
private
def push_add_notice
UsersPusher.new(user).add_notice(self).push
end
et puis vous aurez besoin d'un partiel, par exemple app/views/users_pusher/add_notice.js.haml, qui pourrait être aussi simple que:
alert('#{@notice.body}')
Je suppose que vous n'avez pas vraiment besoin de le faire avec des États d'intérieur de la classe et de l' .pousser
à la fin, mais je voulais la faire ressembler à ActiveMailer. J'ai aussi un
pusher_key méthode sur mon modèle d'utilisateur, de faire un canal pour chaque utilisateur, mais ce
c'est mon premier jour avec quelque chose comme Pusher, donc je ne peux pas dire à coup sûr si c'est la bonne
de la stratégie. Il n'y a plus à être précisées, mais c'est assez pour moi pour commencer.
Bonne chance!
(c'était mon premier brouillon de la réponse, de le laisser, car il pourrait aider quelqu'un)
J'ai le plan général d'une solution de travail. Comme cela, dans votre modèle:
after_create :push_new_message
private
def render_anywhere(partial, assigns = {})
view = ActionView::Base.new(ActionController::Base.view_paths, assigns)
view.extend ApplicationHelper
view.render(:partial => partial)
end
def push_new_message
pushstring = render_anywhere('notices/push_new_message', :message_text => self.body)
Pusher[user.pusher_key].trigger!('new_message', pushstring)
end
c'est certainement de travail - le modèle est rendu, et obtient la fonction eval()'ed sur le côté client avec succès. J'ai l'intention de le nettoyer, presque à coup sûr en render_anywhere quelque part plus général, et probablement essayer quelque chose comme ceci
Je peux voir qui pousse auront besoin de leurs propres modèles, l'appel de la généralement disponibles, et je peut essayer de recueillir tous dans un seul endroit. Un joli petit problème est que j'utilise parfois nom_controller dans mes partiels, comme à la lumière d'un élément de menu, mais je vais bien sûr prendre une tactique différente là. Je devine que je pourrais avoir à faire quelque chose pour obtenir plus d'aides disponibles, mais je ne l'ai pas encore là.
Succès! Hourra! Cela devrait répondre à votre question, et la mienne - je vais ajouter plus de détails si cela semble approprié plus tard. Bonne chance!!!!
d'origine non-réponse à partir d'une heure à gauche pour plus de clarté
Je n'ai pas de réponse, mais ce en temps opportun question mérite plus de précisions, et je suis l'espoir d'obtenir plus près à ma réponse en l'aidant à se demander :)
Je suis confrontée au même problème. Pour expliquer un peu plus clairement, Poussoir de manière asynchrone envoie le contenu à un utilisateur connecté au navigateur. Un cas d'utilisation typique serait une montrant à l'utilisateur ils ont un nouveau message d'un autre utilisateur. Avec Poussoir, vous pouvez envoyer un message au récepteur du navigateur, afin qu'ils obtiennent une notification immédiate si ils sont connectés. Pour une très belle démonstration de ce que le Poussoir peut faire, découvrez http://wordsquared.com/
Vous pouvez envoyer toutes les données que vous aimez, comme un JSON de hachage pour interpréter la manière dont vous l'aimez, mais il serait très pratique pour envoyer des RJS, comme avec tout autre appel ajax et de la fonction eval() sur le côté client. De cette façon, vous pouvez (par exemple) de rendre le modèle de votre barre de menu, la mise à jour dans son intégralité, ou tout simplement le nouveau nombre de message affiché à l'utilisateur, en utilisant tous la même partiels pour le garder SEC. En principe, vous pourriez rendre l'partielle de l' expéditeur du contrôleur, mais cela ne fait pas beaucoup de sens non plus, et il pourrait même ne pas être une demande, il pourrait être déclenché par une tâche cron, par exemple, ou d'un autre événement, comme une action de changement de prix. L'expéditeur contrôleur devrait juste pas savoir à ce sujet - je tiens à garder mes contrôleurs sur un régime de famine ;)
Il peut sembler comme une violation de la MVC, mais c'est vraiment pas - et il ne devrait vraiment être résolu avec quelque chose comme ActionMailer, mais le partage des aides et harmoniques avec le reste de l'application. Je sais que dans mon application, je voudrais envoyer un Poussoir événement au même moment (ou au lieu) d'un ActionMailer appel. Je veux rendre un arbitraire partielle pour l'utilisateur B basée sur un événement de l'utilisateur A.
Ces liens peuvent pointer vers la voie d'une solution:
La dernière semble la plus prometteuse, en offrant cette alléchante extrait:
def render_anywhere(partial, assigns)
view = ActionView::Base.new(Rails::Configuration.new.view_path, assigns)
ActionView::Base.helper_modules.each { |helper| view.extend helper }
view.extend ApplicationHelper
view.render(:partial => partial)
end
Comme ce lien fourni par une autre affiche ci-dessus.
Je vais rendre compte si je reçois quelque chose de travail
tl;dr: moi aussi!