代码之家  ›  专栏  ›  技术社区  ›  Matthew Stopa

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

  •  8
  • Matthew Stopa  · 技术社区  · 16 年前

    我一直在努力让自己的头周围渲染,但我没有太大的成功。

    基本上我有控制器方法:

    def first
      #I want to get the value of VAR1 here
    end
    
    def second
      VAR1 = ["Hello", "Goodbye"]
      render_to ??
    end
    

    我不明白的是如何做到这一点。最初我只想呈现第一个.html.erb文件,但这似乎也不起作用。

    谢谢

    编辑:我很感激我收到的答案,但是所有答案都倾向于避免使用渲染方法或重定向到。那么基本上情况是,你不能把变量从一个控制器传递到另一个控制器吗?我不得不想有办法,但我似乎找不到。

    4 回复  |  直到 8 年前
        1
  •  22
  •   Community CDub    8 年前

    将对象赋给常量不是一个好主意。是的,这是在全局空间中,但对每个人来说都是全局的,因此任何其他进入此请求的用户都将获得此对象。有一些解决办法。

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

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

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

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

        2
  •  2
  •   Andy Gaskell    16 年前

    我通常不让我的控制器互相呼叫对方的动作。如果您有一个以大写字母开头的标识符,那么在Ruby中,它是一个常量。如果要使用实例级变量,请以@开头。

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

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

        3
  •  2
  •   Judson    15 年前

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

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

    def first
      flash[:var] = ["hello", "goodbye"]
      redirect_to :action => :second
    end
    
    def second
      @hello = flash[:var].first
    end
    
        4
  •  2
  •   Iman Tumorang    8 年前
    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
      flash提供了在操作之间传递临时对象的方法。你在闪光灯中放置的任何东西都将暴露在下一个动作中,然后被清除。
       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缓存。

        Rails.cache.write("list",[1,2,3])
        Rails.cache.read("list")
      
      但是当不同的会话有不同的值时会发生什么呢? 除非确保会话中列表名称的唯一性,否则此解决方案将在并发请求期间失败。
    6. 6路
      在一个操作中,根据会话ID将值存储在db表中,其他操作可以根据会话ID从db中检索该值。

    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路
      从操作发送到视图,再从视图发送到控制器中的其他操作。