Rails,如何在模型中呈现视图/部分

时间:2022-10-08 14:19:36

In my model I have:

在我的模型中:

after_create :push_create

I push_create I need to render a view. I'm trying to do that like so:

我push_create我需要呈现一个视图。我试着这样做:

  def push_event(event_type)
    X["XXXXX-#{Rails.env}"].trigger(event_type, 
      {
        :content => render( :partial =>"feeds/feed_item", :locals => { :feed_item => self })
      }
    )
  end

This angers rails as it doesn't like me rendering a view in the model but I need it there.

这激怒了rails,因为它不喜欢我在模型中呈现视图,但我需要它。

Error:

错误:

NoMethodError (undefined method `render' for #<WallFeed:0x1039be070>):

Suggestions? Should I render it somewhere else somehow? Or how can I render in the model to set content? Thanks

建议吗?我应该把它渲染到别的地方吗?或者我如何在模型中渲染以设置内容?谢谢

9 个解决方案

#1


64  

proper solution

Well, "they" are right. You really have to do the rendering in a controller - but it's fair game to call that controller from a model! Fortunately, AbstractController in Rails 3 makes it easier than I thought. I wound up making a simple ActionPusher class, working just like ActionMailer. Perhaps I'll get ambitious and make this a proper gem someday, but this should serve as a good start for anyone else in my shoes.

好,“他们”是正确的。你确实需要在控制器中进行渲染——但是从模型中调用控制器是公平的!幸运的是,Rails 3中的AbstractController比我想象的要简单。我最后创建了一个简单的ActionPusher类,就像ActionMailer一样工作。也许有一天我会变得雄心勃勃,把它变成一颗真正的宝石,但这对任何处在我位置的人来说都是一个好的开始。

I got the most help from this link: http://www.amberbit.com/blog/2011/12/27/render-views-and-partials-outside-controllers-in-rails-3/

这个链接给了我最大的帮助:http://www.amberbit.com/blog/2011/12/27/render-view -and-partials-outside- controllerinrails3/

in lib/action_pusher.rb

在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

in app/pushers/users_pusher.rb. I guess the require could go somewhere more global?

在app / / users_pusher.rb推动者。我想这要求可以在更全球化的地方进行?

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

Now in my model, I can just do this:

在我的模型中,我可以这样做:

after_commit :push_add_notice

private

def push_add_notice
  UsersPusher.new(user).add_notice(self).push
end

and then you'll want a partial, e.g. app/views/users_pusher/add_notice.js.haml, which could be as simple as:

然后你会想要一个局部的,例如app/views/users_pusher/ add_notification .js。haml,可以很简单:

alert('#{@notice.body}')

I guess you don't really need to do it with Pushable inner class and the .push call at the end, but I wanted to make it look like ActiveMailer. I also have a pusher_key method on my user model, to make a channel for each user - but this is my first day with anything like Pusher, so I can't say for sure if that's the right strategy. There's more to be fleshed out, but this is enough for me to get started.

我猜你不需要使用可推的内部类和结尾的。push调用,但是我想让它看起来像ActiveMailer。我在我的用户模型上也有一个pusher_key方法,为每个用户创建一个通道——但是这是我第一天使用任何东西,比如Pusher,所以我不能肯定这是否是正确的策略。还有更多的东西需要充实,但这已经足够让我开始了。

Good luck!

好运!

(this was my first draft answer, leaving it in because it might help someone)

I've got the general outline of a solution working. Like this, in your model:

我有一个解决方案的大致轮廓。就像这样,在你的模型中:

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

that is definitely working - the template is rendering, and gets eval()'ed on the client side successfully. I'm planning to clean it up, almost certainly move render_anywhere somewhere more general, and probably try something like this

这显然是可行的——模板正在呈现,并在客户端成功地获取eval() ed。我打算把它清理干净,几乎可以肯定地把render_where更一般的地方,并可能尝试类似的东西

I can see that pushes will need their own templates, calling the generally available ones, and I may try to collect them all in one place. One nice little problem is that I sometimes use controller_name in my partials, like to light up a menu item, but I'll obviously have to take a different tactic there. I'm guessing I might have to do something to get more helpers available, but I haven't gotten there yet.

我可以看到push将需要它们自己的模板,调用一般可用的模板,我可以尝试在一个地方收集它们。一个很好的小问题是,有时我在部分中使用controller_name,比如点亮菜单项,但显然我必须采取不同的策略。我想我可能得做点什么才能找到更多的帮手,但我还没到那一步。

Success! Hooray! This should answer your question, and mine - I'll add more detail if it seems appropriate later. Good luck!!!!

成功!万岁!这应该能回答你的问题,也能回答我的问题。祝你好运! ! ! !

original non-answer from an hour ago left for clarity

I don't have an answer, but this timely question deserves more clarification, and I'm hoping to get closer to my answer by helping ask :)

我没有答案,但这个及时的问题需要更多的澄清,我希望通过帮助提问来接近我的答案。

I'm facing the same problem. To explain a little more clearly, Pusher asynchronously sends content to a connected user browser. A typical use case would be a showing the user they have a new message from another user. With Pusher, you can push a message to the receiver's browser, so they get an immediate notification if they are logged in. For a really great demo of what Pusher can do, check out http://wordsquared.com/

我也面临同样的问题。为了更清楚地解释,Pusher会异步地将内容发送到连接的用户浏览器。一个典型的用例是向用户显示他们有来自另一个用户的新消息。使用Pusher,您可以将消息推送到接收方的浏览器,因此,如果他们登录,就会立即收到通知。要了解Pusher的功能,请查看http://wordsquaredcom/

You can send any data you like, such as a JSON hash to interpret how you like it, but it would be very convenient to send RJS, just like with any other ajax call and eval() it on the client side. That way, you could (for example) render the template for your menu bar, updating it in its entirety, or just the new message count displayed to the user, using all the same partials to keep it bone-DRY. In principle, you could render the partial from the sender's controller, but that doesn't make much sense either, and there might not even be a request, it could be triggered by a cron job, for example, or some other event, like a stock price change. The sender controller just should not have to know about it - I like to keep my controllers on a starvation diet ;)

您可以发送任何您喜欢的数据,比如一个JSON散列来解释您喜欢的数据,但是发送RJS会非常方便,就像在客户端使用其他ajax调用和eval()一样。这样,您就可以(例如)呈现菜单栏的模板,完整地更新模板,或者只更新显示给用户的新消息计数,使用所有相同的部分保持它的干爽。原则上,您可以从发送方的控制器中呈现部分内容,但这也没有多大意义,甚至可能没有请求,它可能由cron作业触发,例如,或其他事件,如股票价格变化。发送方控制器不需要知道它——我喜欢让我的控制器处于饥饿状态;

It might sound like a violation of MVC, but it's really not - and it really should be solved with something like ActionMailer, but sharing helpers and partials with the rest of the app. I know in my app, I'd like to send a Pusher event at the same time as (or instead of) an ActionMailer call. I want to render an arbitrary partial for user B based on an event from user A.

它听起来像一个违反了MVC,但这真的不是,真的应该解决类似的邮件,但分享助手和泛音与其它应用程序。我知道在我的应用程序,我想寄一个推杆式事件的同时(或相反)的一个邮件器调用。我想根据用户A的事件为用户B呈现任意的部分。

These links may point the way towards a solution:

这些链接可能指向解决方案:

The last one looks the most promising, offering up this tantalizing snippet:

最后一个看起来最有希望,提供了这个诱人的片段:

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

As does this link provided by another poster above.

上面另一张海报也提供了这个链接。

I'll report back if I get something working

如果我有什么事可以做,我就回去报告

tl;dr: me too!

tl;博士:我也是!

#2


57  

I just do this:

我只是这样做:

ApplicationController.new.render_to_string(partial: 'messages/any', locals: { variable: 'value' })

#3


20  

You can use ActionView directly and render partials to string without having a controller. I find that pattern useful to create models that encapsulate some javascript generation, for instance.

您可以直接使用ActionView来呈现字符串的部分,而无需使用控制器。例如,我发现这个模式很有用,可以创建封装一些javascript生成的模型。

html = ActionView::Base.new(Rails.configuration.paths['app/views']).render(
  partial: 'test', 
  formats: [:html],
  handlers: [:erb],
  locals: { variable: 'value' }
)

Then, just put your _test.html.erb in you view folder and try it out!

然后,输入_test.html。erb在你的视图文件夹和尝试它!

#4


17  

Rails 5 way

In Rails 5 rendering outside a controller became pretty straightforward due to implemented render controller class method:

在Rails 5中,由于实现了呈现控制器类方法,控制器外的呈现变得非常简单:

# render template
ApplicationController.render 'templates/name'
# render action
FooController.render :index
# render file
ApplicationController.render file: 'path'
# render inline
ApplicationController.render inline: 'erb content'

When calling render outside of a controller, one can assign instance variables via assigns option and use any other options available from within a controller:

当调用控制器外部的呈现时,可以通过assign选项分配实例变量,并使用控制器内部可用的任何其他选项:

ApplicationController.render(
  assigns: { article: Article.take },
  template: 'articles/show',
  layout: false
)

Request environment can be tailored either through default options

请求环境可以通过默认选项进行调整

ApplicationController.render inline: '<%= users_url %>'
# => 'http://default_host.com/users'

ApplicationController.renderer.defaults[:http_host] = 'custom_host.org'
# => "custom_host.org"

ApplicationController.render inline: '<%= users_url %>'
# => 'http://custom_host.org/users'

or explicitly by initializing a new renderer

或者显式地初始化一个新的渲染器

renderer = ApplicationController.renderer.new(
  http_host: 'custom_host.org',
  https: true
)
renderer.render inline: '<%= users_url %>'
# => 'https://custom_host.org/users'

Hope that helps.

希望有帮助。

#5


2  

I'm fairly sure the answers you seek lie within Crafting Rails Applications where Jose Valim goes into great detail about how and why you would want to render views straight from your db

我确信您所寻求的答案存在于开发Rails应用程序中,Jose Valim详细介绍了您希望直接从db中呈现视图的方式和原因

Sorry I can't be of more help yet because I've just started reading it myself tonight.

对不起,我帮不了你什么忙,因为我今晚才开始读这本书。

You might find some help here - it's a blog post about doing this sort of thing, albeit using different methods than yours

你可以在这里找到一些帮助——这是一篇关于做这类事情的博客文章,尽管使用的方法与你的不同

#6


2  

the "proper" way to do this is to push an object in serialized form(json), and then have the view deal with it once the event is received. Perhaps you want to use Handlebars to render the object.

这样做的“正确”方法是推入一个序列化格式(json)的对象,然后在接收到事件后让视图处理它。也许您希望使用Handlebars来呈现对象。

Edit: I originally wrote about how, despite my answer, I was going to follow your example. But I just realized there is a HUGE gotcha with your approach when it comes to push notifications.

编辑:我最初写的是,尽管我给出了答案,但我将如何效仿你。但我刚刚意识到,在推送通知方面,你的方法有一个很大的问题。

In your problem, you are doing push notifications to one user. For me, I was broadcasting out to a set of users. So I was going to render html with a presumption of a "current_user" and all that comes with it(eg logic, permissions, etc). This is NO BUENO as each push notification will be received by a different "current user".

在您的问题中,您正在对一个用户执行推送通知。对我来说,我是在向一群用户广播。因此,我将使用一个“current_user”的假设来呈现html,以及所有附带的内容(如逻辑、权限等)。这不是布埃诺,因为每个推送通知将被不同的“当前用户”接收。

Therefore, really, you need to just send back the data, and let each individual view handle it.

因此,实际上,您需要返回数据,并让每个视图处理它。

#7


0  

You should call all render methods from a controller. So, in this case, you can notify the controller that the object has been created and the controller can then render the view. Also, since you can render only once, I think you can wait for all your server side operations to complete before invoking the render.

您应该调用控制器中的所有呈现方法。因此,在这种情况下,您可以通知控制器对象已经创建,然后控制器可以呈现视图。而且,由于您只能渲染一次,我认为您可以在调用渲染之前等待所有服务器端操作完成。

#8


0  

The render methods are defined on the ActiveController class and its progeny. Inherently you do not have access to it on the model, nor is it a class method so you can't use it without an instance of the controller.

呈现方法是在ActiveController类及其子代上定义的。从本质上来说,您不能在模型*问它,它也不是一个类方法,因此您不能在没有控制器实例的情况下使用它。

I've never tried to instantiate a controller for the express purpose of simply stringifying a partial, but if you can get your hands on a controller, render_to_string seems to be the way to go.

我从来没有尝试过实例化一个控制器,目的是为了简单地对一个部分进行字符串化,但是如果您能够得到一个控制器,render_to_string似乎是正确的方法。

I will chime in by saying that if you're going down this path you're taking RoR "off the Rails". This is a violation of MVC and fundamentally poor program design.This doesn't mean I think you're a bad person :P Sometimes life drives us off the rails, so to speak.

我会插嘴说,如果你沿着这条路走下去,你会把魔镜“脱轨”。这违反了MVC,并且从根本上说是糟糕的程序设计。这并不意味着我认为你是一个坏的人:有时候,生活让我们偏离了轨道。

I can't speak to the details that have driven you to do this, but I'd strongly suggest you rethink your approach.

我无法说出促使你这么做的细节,但我强烈建议你重新考虑你的方法。

#9


0  

I have created a gist for this.
I needed something similar, where the models don't necessarily (or in my case, ever) get updated via a controller, so the logic can't sit there.

我为此写了一个要点。我需要类似的东西,其中模型不一定(在我的例子中,从来没有)通过控制器更新,所以逻辑不能放在那里。

Created a server-push based controller:
https://gist.github.com/4707055

创建了一个基于服务器推送的控制器:https://gist.github.com/47070705555

#1


64  

proper solution

Well, "they" are right. You really have to do the rendering in a controller - but it's fair game to call that controller from a model! Fortunately, AbstractController in Rails 3 makes it easier than I thought. I wound up making a simple ActionPusher class, working just like ActionMailer. Perhaps I'll get ambitious and make this a proper gem someday, but this should serve as a good start for anyone else in my shoes.

好,“他们”是正确的。你确实需要在控制器中进行渲染——但是从模型中调用控制器是公平的!幸运的是,Rails 3中的AbstractController比我想象的要简单。我最后创建了一个简单的ActionPusher类,就像ActionMailer一样工作。也许有一天我会变得雄心勃勃,把它变成一颗真正的宝石,但这对任何处在我位置的人来说都是一个好的开始。

I got the most help from this link: http://www.amberbit.com/blog/2011/12/27/render-views-and-partials-outside-controllers-in-rails-3/

这个链接给了我最大的帮助:http://www.amberbit.com/blog/2011/12/27/render-view -and-partials-outside- controllerinrails3/

in lib/action_pusher.rb

在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

in app/pushers/users_pusher.rb. I guess the require could go somewhere more global?

在app / / users_pusher.rb推动者。我想这要求可以在更全球化的地方进行?

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

Now in my model, I can just do this:

在我的模型中,我可以这样做:

after_commit :push_add_notice

private

def push_add_notice
  UsersPusher.new(user).add_notice(self).push
end

and then you'll want a partial, e.g. app/views/users_pusher/add_notice.js.haml, which could be as simple as:

然后你会想要一个局部的,例如app/views/users_pusher/ add_notification .js。haml,可以很简单:

alert('#{@notice.body}')

I guess you don't really need to do it with Pushable inner class and the .push call at the end, but I wanted to make it look like ActiveMailer. I also have a pusher_key method on my user model, to make a channel for each user - but this is my first day with anything like Pusher, so I can't say for sure if that's the right strategy. There's more to be fleshed out, but this is enough for me to get started.

我猜你不需要使用可推的内部类和结尾的。push调用,但是我想让它看起来像ActiveMailer。我在我的用户模型上也有一个pusher_key方法,为每个用户创建一个通道——但是这是我第一天使用任何东西,比如Pusher,所以我不能肯定这是否是正确的策略。还有更多的东西需要充实,但这已经足够让我开始了。

Good luck!

好运!

(this was my first draft answer, leaving it in because it might help someone)

I've got the general outline of a solution working. Like this, in your model:

我有一个解决方案的大致轮廓。就像这样,在你的模型中:

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

that is definitely working - the template is rendering, and gets eval()'ed on the client side successfully. I'm planning to clean it up, almost certainly move render_anywhere somewhere more general, and probably try something like this

这显然是可行的——模板正在呈现,并在客户端成功地获取eval() ed。我打算把它清理干净,几乎可以肯定地把render_where更一般的地方,并可能尝试类似的东西

I can see that pushes will need their own templates, calling the generally available ones, and I may try to collect them all in one place. One nice little problem is that I sometimes use controller_name in my partials, like to light up a menu item, but I'll obviously have to take a different tactic there. I'm guessing I might have to do something to get more helpers available, but I haven't gotten there yet.

我可以看到push将需要它们自己的模板,调用一般可用的模板,我可以尝试在一个地方收集它们。一个很好的小问题是,有时我在部分中使用controller_name,比如点亮菜单项,但显然我必须采取不同的策略。我想我可能得做点什么才能找到更多的帮手,但我还没到那一步。

Success! Hooray! This should answer your question, and mine - I'll add more detail if it seems appropriate later. Good luck!!!!

成功!万岁!这应该能回答你的问题,也能回答我的问题。祝你好运! ! ! !

original non-answer from an hour ago left for clarity

I don't have an answer, but this timely question deserves more clarification, and I'm hoping to get closer to my answer by helping ask :)

我没有答案,但这个及时的问题需要更多的澄清,我希望通过帮助提问来接近我的答案。

I'm facing the same problem. To explain a little more clearly, Pusher asynchronously sends content to a connected user browser. A typical use case would be a showing the user they have a new message from another user. With Pusher, you can push a message to the receiver's browser, so they get an immediate notification if they are logged in. For a really great demo of what Pusher can do, check out http://wordsquared.com/

我也面临同样的问题。为了更清楚地解释,Pusher会异步地将内容发送到连接的用户浏览器。一个典型的用例是向用户显示他们有来自另一个用户的新消息。使用Pusher,您可以将消息推送到接收方的浏览器,因此,如果他们登录,就会立即收到通知。要了解Pusher的功能,请查看http://wordsquaredcom/

You can send any data you like, such as a JSON hash to interpret how you like it, but it would be very convenient to send RJS, just like with any other ajax call and eval() it on the client side. That way, you could (for example) render the template for your menu bar, updating it in its entirety, or just the new message count displayed to the user, using all the same partials to keep it bone-DRY. In principle, you could render the partial from the sender's controller, but that doesn't make much sense either, and there might not even be a request, it could be triggered by a cron job, for example, or some other event, like a stock price change. The sender controller just should not have to know about it - I like to keep my controllers on a starvation diet ;)

您可以发送任何您喜欢的数据,比如一个JSON散列来解释您喜欢的数据,但是发送RJS会非常方便,就像在客户端使用其他ajax调用和eval()一样。这样,您就可以(例如)呈现菜单栏的模板,完整地更新模板,或者只更新显示给用户的新消息计数,使用所有相同的部分保持它的干爽。原则上,您可以从发送方的控制器中呈现部分内容,但这也没有多大意义,甚至可能没有请求,它可能由cron作业触发,例如,或其他事件,如股票价格变化。发送方控制器不需要知道它——我喜欢让我的控制器处于饥饿状态;

It might sound like a violation of MVC, but it's really not - and it really should be solved with something like ActionMailer, but sharing helpers and partials with the rest of the app. I know in my app, I'd like to send a Pusher event at the same time as (or instead of) an ActionMailer call. I want to render an arbitrary partial for user B based on an event from user A.

它听起来像一个违反了MVC,但这真的不是,真的应该解决类似的邮件,但分享助手和泛音与其它应用程序。我知道在我的应用程序,我想寄一个推杆式事件的同时(或相反)的一个邮件器调用。我想根据用户A的事件为用户B呈现任意的部分。

These links may point the way towards a solution:

这些链接可能指向解决方案:

The last one looks the most promising, offering up this tantalizing snippet:

最后一个看起来最有希望,提供了这个诱人的片段:

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

As does this link provided by another poster above.

上面另一张海报也提供了这个链接。

I'll report back if I get something working

如果我有什么事可以做,我就回去报告

tl;dr: me too!

tl;博士:我也是!

#2


57  

I just do this:

我只是这样做:

ApplicationController.new.render_to_string(partial: 'messages/any', locals: { variable: 'value' })

#3


20  

You can use ActionView directly and render partials to string without having a controller. I find that pattern useful to create models that encapsulate some javascript generation, for instance.

您可以直接使用ActionView来呈现字符串的部分,而无需使用控制器。例如,我发现这个模式很有用,可以创建封装一些javascript生成的模型。

html = ActionView::Base.new(Rails.configuration.paths['app/views']).render(
  partial: 'test', 
  formats: [:html],
  handlers: [:erb],
  locals: { variable: 'value' }
)

Then, just put your _test.html.erb in you view folder and try it out!

然后,输入_test.html。erb在你的视图文件夹和尝试它!

#4


17  

Rails 5 way

In Rails 5 rendering outside a controller became pretty straightforward due to implemented render controller class method:

在Rails 5中,由于实现了呈现控制器类方法,控制器外的呈现变得非常简单:

# render template
ApplicationController.render 'templates/name'
# render action
FooController.render :index
# render file
ApplicationController.render file: 'path'
# render inline
ApplicationController.render inline: 'erb content'

When calling render outside of a controller, one can assign instance variables via assigns option and use any other options available from within a controller:

当调用控制器外部的呈现时,可以通过assign选项分配实例变量,并使用控制器内部可用的任何其他选项:

ApplicationController.render(
  assigns: { article: Article.take },
  template: 'articles/show',
  layout: false
)

Request environment can be tailored either through default options

请求环境可以通过默认选项进行调整

ApplicationController.render inline: '<%= users_url %>'
# => 'http://default_host.com/users'

ApplicationController.renderer.defaults[:http_host] = 'custom_host.org'
# => "custom_host.org"

ApplicationController.render inline: '<%= users_url %>'
# => 'http://custom_host.org/users'

or explicitly by initializing a new renderer

或者显式地初始化一个新的渲染器

renderer = ApplicationController.renderer.new(
  http_host: 'custom_host.org',
  https: true
)
renderer.render inline: '<%= users_url %>'
# => 'https://custom_host.org/users'

Hope that helps.

希望有帮助。

#5


2  

I'm fairly sure the answers you seek lie within Crafting Rails Applications where Jose Valim goes into great detail about how and why you would want to render views straight from your db

我确信您所寻求的答案存在于开发Rails应用程序中,Jose Valim详细介绍了您希望直接从db中呈现视图的方式和原因

Sorry I can't be of more help yet because I've just started reading it myself tonight.

对不起,我帮不了你什么忙,因为我今晚才开始读这本书。

You might find some help here - it's a blog post about doing this sort of thing, albeit using different methods than yours

你可以在这里找到一些帮助——这是一篇关于做这类事情的博客文章,尽管使用的方法与你的不同

#6


2  

the "proper" way to do this is to push an object in serialized form(json), and then have the view deal with it once the event is received. Perhaps you want to use Handlebars to render the object.

这样做的“正确”方法是推入一个序列化格式(json)的对象,然后在接收到事件后让视图处理它。也许您希望使用Handlebars来呈现对象。

Edit: I originally wrote about how, despite my answer, I was going to follow your example. But I just realized there is a HUGE gotcha with your approach when it comes to push notifications.

编辑:我最初写的是,尽管我给出了答案,但我将如何效仿你。但我刚刚意识到,在推送通知方面,你的方法有一个很大的问题。

In your problem, you are doing push notifications to one user. For me, I was broadcasting out to a set of users. So I was going to render html with a presumption of a "current_user" and all that comes with it(eg logic, permissions, etc). This is NO BUENO as each push notification will be received by a different "current user".

在您的问题中,您正在对一个用户执行推送通知。对我来说,我是在向一群用户广播。因此,我将使用一个“current_user”的假设来呈现html,以及所有附带的内容(如逻辑、权限等)。这不是布埃诺,因为每个推送通知将被不同的“当前用户”接收。

Therefore, really, you need to just send back the data, and let each individual view handle it.

因此,实际上,您需要返回数据,并让每个视图处理它。

#7


0  

You should call all render methods from a controller. So, in this case, you can notify the controller that the object has been created and the controller can then render the view. Also, since you can render only once, I think you can wait for all your server side operations to complete before invoking the render.

您应该调用控制器中的所有呈现方法。因此,在这种情况下,您可以通知控制器对象已经创建,然后控制器可以呈现视图。而且,由于您只能渲染一次,我认为您可以在调用渲染之前等待所有服务器端操作完成。

#8


0  

The render methods are defined on the ActiveController class and its progeny. Inherently you do not have access to it on the model, nor is it a class method so you can't use it without an instance of the controller.

呈现方法是在ActiveController类及其子代上定义的。从本质上来说,您不能在模型*问它,它也不是一个类方法,因此您不能在没有控制器实例的情况下使用它。

I've never tried to instantiate a controller for the express purpose of simply stringifying a partial, but if you can get your hands on a controller, render_to_string seems to be the way to go.

我从来没有尝试过实例化一个控制器,目的是为了简单地对一个部分进行字符串化,但是如果您能够得到一个控制器,render_to_string似乎是正确的方法。

I will chime in by saying that if you're going down this path you're taking RoR "off the Rails". This is a violation of MVC and fundamentally poor program design.This doesn't mean I think you're a bad person :P Sometimes life drives us off the rails, so to speak.

我会插嘴说,如果你沿着这条路走下去,你会把魔镜“脱轨”。这违反了MVC,并且从根本上说是糟糕的程序设计。这并不意味着我认为你是一个坏的人:有时候,生活让我们偏离了轨道。

I can't speak to the details that have driven you to do this, but I'd strongly suggest you rethink your approach.

我无法说出促使你这么做的细节,但我强烈建议你重新考虑你的方法。

#9


0  

I have created a gist for this.
I needed something similar, where the models don't necessarily (or in my case, ever) get updated via a controller, so the logic can't sit there.

我为此写了一个要点。我需要类似的东西,其中模型不一定(在我的例子中,从来没有)通过控制器更新,所以逻辑不能放在那里。

Created a server-push based controller:
https://gist.github.com/4707055

创建了一个基于服务器推送的控制器:https://gist.github.com/47070705555