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

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

问题描述:

我一直在试图让我的头在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的。基本上是这样的,你不能将变量从控制器传递到控制器?我必须认为,有某种方式,但我似乎无法找到它。

将对象赋给常量不是一个好主意。确实这是在全局空间中,但它对每个人都是全局的,所以任何其他用户都会收到此请求。有几个解决方案。

我假设你有一个多步骤的形式,你正在经历。在这种情况下,您可以将设置属性作为隐藏字段传递。

<%= 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

+0

嗨瑞安,会话选项仍然在Rails 3中有效吗?如果我存储'@ item.attributes' IT卖场保护像ID和时间戳为无属性,试图从这个会话建立一个新的对象后导致MassAssignmentSecurity错误 – Noz 2012-09-28 17:37:28

+0

'object.attributes.slice(“字段1”,“字段2” )'似乎是要走的路,只需将field1和field2替换为所需的任何字段即可。 – Noz 2012-09-28 17:45:12

+0

真棒瑞恩我一直在寻找这个答案很长一段时间! – Cas 2015-06-11 02:58:50

我通常没有我的控制器调用对方的动作。如果你有一个以大写字母开头的标识符,在Ruby中是一个常量。如果你想要一个实例级别的变量,让它以@开头。

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

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

+0

从本质上讲,我试图做一个多步骤的过程,其中一个用户上传文件,然后我处理它,并重新目前它回给他们,让他们做出一些改变它,最后将其插入进入数据库。 要做到这一点,虽然我需要能够向对象传递到另一个控制器或至少另一个控制器视图。 – 2009-08-17 07:28:10

+0

不是这样做,为什么不是你运作的中间结果存储在数据库中,并将它标志为未完成。通过这种方式,您知道您可以像平常一样通过模型访问它,并且可以适应服务器故障。 – 2009-08-17 12:08:03

你有没有考虑使用闪存散列?很多人只是将它用于错误消息等,它明确表示您可能感兴趣的那种瞬态数据传递。

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

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

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

  1. 方式1
    全局变量 (并发请求过程中失败)
  2. 方式2
    类变量 (并发请求过程中失败)
  3. 方式3

    • 藏匿请求之间的服务器上的对象。典型的方法是将它保存在会话中,因为它会自动为您序列化/反序列化对象。
    • 序列化对象,并包括它的形式某处,并从 在未来请求中的参数反序列化。所以你可以在会话中存储属性。

       
      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 
      
  4. 方式4
    闪光灯提供了一种方式来传递动作之间的临时对象。你放在闪光灯中的任何东西都会暴露在下一个动作中,然后被清除。
     
    def new 
        @test_suite_run = TestSuiteRun.new 
        @tests = Test.find(:all, :conditions => { :test_suite_id => params[:number] }) 
        flash[:someval] = params[:number] 
    end 
    def create
    @test_suite_run = TestSuiteRun.new(params[:test_suite_run]) @tests = Test.find(:all, :conditions => { :test_suite_id => flash[:someval] })
    end
  5. 方式5
    你可以使用轨道缓存。

     
        Rails.cache.write("list",[1,2,3]) 
        Rails.cache.read("list") 
    
    但是,当不同的会话有不同的价值观会发生什么? 除非你保证列表名称的唯一性在整个会话并发请求

  6. 方式在此解决方案将失败6
    在一个行为存储基于会话ID和其他行动可以检索它在数据库表中的值基于会话ID的数据库。

  7. 方式7

     
    class BarsController < UsersController
    before_filter :init_foo_list

    def method1 render :method2 end

    def method2 @foo_list.each do | item| # do something end end

    def init_foo_list @foo_list ||= ['Money', 'Animals', 'Ummagumma'] end end

  8. 方式8
    从动作发送到从视图发送到控制器的其他操作查看和试。