如何在 Rails 中将对象从一个控制器传递到另一个控制器?

Posted

技术标签:

【中文标题】如何在 Rails 中将对象从一个控制器传递到另一个控制器?【英文标题】:How can I pass objects from one controller to another in rails? 【发布时间】:2010-11-20 04:01:10 【问题描述】:

我一直在尝试了解 render_to,但没有取得多大成功。

基本上我有控制器方法:

def first
  #I want to get the value of VAR1 here
end

def second
  VAR1 = ["Hello", "Goodbye"]
  render_to ??
end

我不知道如何做到这一点。最初我只是想渲染 first.html.erb 文件,但这似乎也不起作用。

谢谢

编辑:我很欣赏我收到的答案,但是他们都倾向于避免使用渲染方法或redirect_to。基本上是不是你不能将变量从控制器传递到控制器?我必须认为有某种方法,但我似乎找不到它。

【问题讨论】:

【参考方案1】:

我通常不会让我的控制器调用彼此的操作。如果您有一个以大写字母开头的标识符,那么在 Ruby 中这是一个常量。如果你想要一个实例级变量,让它以@开头。

@var1 = ["Hello", "Goodbye"]

你能解释一下你的目标是什么吗?

【讨论】:

基本上我正在尝试执行一个多步骤过程,其中用户上传文件,然后我处理它并将其重新呈现给他们,让他们对其进行某些更改,然后最后将其插入数据库。为此,我需要能够将该对象传递给另一个控制器或至少另一个控制器视图。 与其这样做,为什么不将工作的中间结果存储在数据库中并将其标记为不完整。这样你就知道你可以像往常一样通过模型访问它,并且你可以适应服务器故障。【参考方案2】:

将对象分配给常量不是一个好主意。确实,这是在一个全局空间中,但它对每个人都是全局的,因此任何其他访问此请求的用户都将获得此对象。有几个解决方案。

我假设您正在处理一个多步骤表单。在这种情况下,您可以将设置的属性作为隐藏字段传递。

<%= f.hidden_field :name %>

如果有很多字段,这可能很乏味,因此您可能需要循环通过 params[...] 哈希或 column_names 方法来确定要传递哪些属性。

您也可以将属性存储在session。

def first
  @item = Item.new(params[:item])
  session[:item_attributes] = @item.attributes
end

def second
  @item = Item.new(session[:item_attributes])
  @item.attributes = params[:item]
end

第三,正如Paul Keeble 提到的,您可以将模型保存到数据库中,但将其标记为不完整。您可能需要为此使用state machine。

最后,你可能想看看Acts As Wizard plugin。

【讨论】:

嗨 Ryan,会话选项在 Rails 3 中仍然有效吗?如果我存储 @item.attributes 它将受保护的属性(如 id 和时间戳)存储为 nil,稍后尝试从此会话构建新对象会导致 MassAssignmentSecurity 错误 object.attributes.slice('field1', 'field2') 似乎是只需将 field1 和 field2 替换为所需的任何字段即可。【参考方案3】:

您是否考虑过使用闪存哈希?很多人仅将它用于错误消息等,它明确用于您可能感兴趣的那种瞬态数据传递。

基本上,flash 方法返回一个哈希值。您分配给哈希中的键的任何值都将可用于下一个操作,但随后它就消失了。所以:

def first
  flash[:var] = ["hello", "goodbye"]
  redirect_to :action => :second
end

def second
  @hello = flash[:var].first
end

【讨论】:

【参考方案4】:
    方式 1 全局变量 (在并发请求期间失败) 方式 2 类变量 (在并发请求期间失败)

    方式 3

    在请求之间将对象存储在服务器上。典型的方法是将其保存在会话中,因为它会自动为您序列化/反序列化对象。

    序列化对象并将其包含在表单中的某处,并且 从下一个请求中的参数反序列化它。这样您就可以在会话中存储属性。

    先定义 @item = Item.new(params[:item]) 会话[:item_attributes] = @item.attributes 结尾 定义秒 @item = Item.new(session[:item_attributes]) @item.attributes = 参数[:item] 结尾 方式 4 flash 提供了一种在动作之间传递临时对象的方法。您放入 Flash 中的任何内容都将在下一个动作中暴露出来,然后被清除。
     定义新
       @test_suite_run = TestSuiteRun.new
       @tests = Test.find(:all, :conditions =>  :test_suite_id => params[:number] )
       flash[:someval] = 参数[:number]
     结尾
     定义创建
       @test_suite_run = TestSuiteRun.new(params[:test_suite_run])
       @tests = Test.find(:all, :conditions =>  :test_suite_id => flash[:someval] )
     结束

    方式 5 你可以使用rails缓存。

    Rails.cache.write("list",[1,2,3]) Rails.cache.read("列表") 但是当不同的会话有不同的值时会发生什么呢? 除非您确保整个会话中列表名称的唯一性,否则此解决方案将在并发请求期间失败

    6路 在一个动作中,根据会话 id 将值存储在 db 表中,其他动作可以根据会话 id 从 db 中检索它。

    7路

    类 BarsController before_filter :init_foo_list

    定义方法1 渲染:方法2 结束

    定义方法2 @foo_list.each 做 |项目| # 做一点事 结尾 结束

    def init_foo_list @foo_list ||= ['钱','动物','Ummagumma'] 结尾 结束

    8 路 从动作发送到视图,再从视图发送到控制器中的其他动作。

【讨论】:

以上是关于如何在 Rails 中将对象从一个控制器传递到另一个控制器?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Qt 中将数据从一种形式传递到另一种形式?

如何在 Codeigniter 中将变量从一个控制器传递到另一个控制器

如何在没有 segue 的情况下在 Swift 3 中将数据从 VC 传递到另一个?

Rails 3 - 如何将语句从一个控制器打印到另一个

如何在单页应用程序中以角度将数据从一页传递到另一页

在swift 3中将json id从一个表视图控制器传递到另一个表视图控制器