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

时间:2009-08-17 07:05:05

标签: ruby-on-rails controller model-view-controller

我一直试图把我的头脑放在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文件,但这似乎也没有用。

由于

编辑:我很欣赏我收到的答案,但是所有答案都倾向于避免使用render方法或redirect_to。基本上情况是你不能将变量从控制器传递给控制器​​吗?我不得不认为有一些方法,但我似乎无法找到它。

4 个答案:

答案 0 :(得分:22)

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

我假设您正在经历多步骤表格。在这种情况下,您可以将设置属性作为隐藏字段传递。

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

答案 1 :(得分:2)

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

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

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

答案 2 :(得分:2)

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

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

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

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

答案 3 :(得分:2)

  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 cache。  

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