如何跨重定向缓存ActiveRecord模型对象?

时间:2010-01-10 18:11:44

标签: ruby-on-rails activerecord

这可能是一个新手问题,但我不确定要搜索的条件。

假设我有一个CUSTOMER对象,我想向该客户发送一封消息。

我首先要做的是在CUSTOMER控制器上添加一个SENDMESSAGE操作,它构建了消息对象。 (假设这是正确的做法?)

然而,在这种情况下,我不需要从此动作中实际发送消息,而是转发到MESSAGE的编辑视图以捕获正文等。

问题:我想在不持久化对象的情况下这样做。我想在这里构建对象,然后将其移交给另一个视图以完成。

def sendmessage
    @message = Message.new
    @message.title = 'WIBBLE'
    @message.thecustomer = self
    @message.save    
    respond_to do |format|
      format.html { redirect_to(edit_message_path(@ message)) }
      format.xml  { render :xml => @ message }
    end
end

也许我的问题归结为,在请求和多个屏幕上缓存参数和对象的'轨道方式'是什么。

很高兴能够指向Web URL,因为我希望这很简单。

由于

2 个答案:

答案 0 :(得分:1)

在构建Web应用程序时,在请求之间保留数据的标准方法是使用HTTP会话。 Rails为此目的提供了一个隐式会话哈希。它的使用方式如下:

session[:message] = @message #store
@message = session[:message] #retrieve

您还可以使用Rails flash会话包装器将信息从当前操作传递到下一个操作。它通常用于存储要在UI中显示的文本,但您可以使用它来保存任何对象:

flash[:message] = @message #store
@message = flash[:message] #retrieve

在这两种情况下,您要存储的对象都必须是可序列化的。请注意,默认情况下,Rails将会话数据存储在客户端的加密cookie中;认为这是一个强烈的暗示,在Rails世界中,在会话中存储大量数据是不受欢迎的。

答案 1 :(得分:1)

这实际上是一项相当复杂的常见任务。处理这个问题的Rails方法不是保留有问题的对象,而只是渲染将完成操作的视图。

class CustomersController < Application Controller
  def sendmessage
    @message = Message.new
    @message.title = 'WIBBLE'
    @message.thecustomer = self
    respond_to do |format|
      format.html { render "messages/edit" }
      format.xml  { render :xml => @ message }
    end
  end
end

一般来说,在Rails中跨越HTTP请求持久化整个对象是一个坏主意,唯一真正的方法是通过John Topley建议的会话或闪存哈希,但这两者都受限于可用空间。这就是为什么FrançoisBeausoleil建议只在会话中存储对象id。无论哪种方式,你都应该在完成后清除哈希值。

您应该在这里做的是设计控制器操作,以便每个操作完全完成任务。完成半个任务并重定向所以第二个动作可以完成任务可能稍微干一点,但是,它与Rails控制流程不能很好地融合。如示例所示,控制器操作完成了呈现视图所需的所有处理。

基本上,如果您希望保留信息,因为您正在重定向。您会发现渲染您重定向到的视图更容易。