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

时间:2020-12-16 20:56:21

I have been trying to get my head around render_to but I haven't had much success.

我一直试图把我的头脑放在render_to,但我没有取得多大成功。

Essentially I have controller methods:

基本上我有控制器方法:

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

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

What I can't figure out is how to accomplish that. Originally I just wanted to render the first.html.erb file but that didn't seem to work either.

我无法弄清楚的是如何实现这一目标。最初我只想渲染first.html.erb文件,但这似乎也没有用。

Thanks

Edit: I appreciate the answers I have received, however all of them tend to avoid using the render method or redirect_to. Is it basically the case then that a you cannot pass variables from controller to controller? I have to think that there is some way but I can't seem to find it.

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

4 个解决方案

#1


21  

It is not a good idea to assign the object to a constant. True this is in a global space, but it is global for everyone so any other user going to this request will get this object. There are a few solutions to this.

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

I am assuming you have a multi-step form you are going through. In that case you can pass the set attributes as hidden fields.

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

<%= f.hidden_field :name %>

If there are a lot of fields this can be tedious so you may want to loop through the params[...] hash or column_names method to determine which attributes to pass.

如果有很多字段,这可能很乏味,因此您可能需要循环使用params [...] hash或column_names方法来确定要传递的属性。

Alternatively you can store attributes in the 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

Thirdly, as Paul Keeble mentioned you can save the model to the database but mark it as incomplete. You may want to use a state machine for this.

第三,正如Paul Keeble所提到的,您可以将模型保存到数据库中,但将其标记为不完整。您可能希望使用状态机。

Finally, you may want to take a look at the Acts As Wizard plugin.

最后,您可能需要查看Acts As Wizard插件。

#2


2  

I usually don't have my controllers calling each other's actions. If you have an identifier that starts with a capital letter, in Ruby that is a constant. If you want to an instance level variable, have it start with @.

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

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

Can you explain what your goal is?

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

#3


2  

Have you considered using the flash hash? A lot of people use it solely for error messages and the like, it's explicitly for the sort of transient data passing you might be interested in.

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

Basically, the flash method returns a hash. Any value you assign to a key in the hash will be available to the next action, but then it's gone. So:

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

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

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

#4


2  

  1. way 1
    Global variable (fail during concurrent requests)
  2. 方式1全局变量(并发请求期间失败)

  3. way 2
    class variable (fail during concurrent requests)
  4. 方式2类变量(并发请求期间失败)

  5. way 3

    • Stash the object on the server between requests. The typical way is to save it in the session, since it automatically serializes/deserializes the object for you.
    • 在请求之间存储服务器上的对象。典型的方法是将其保存在会话中,因为它会自动为您对序列化/反序列化对象。

    • Serialize the object and include it in the form somewhere, and deserialize it from the parameters in the next request. so you can store attributes in the 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
      
  6. way 4
    The flash provides a way to pass temporary objects between actions. Anything you place in the flash will be exposed to the very next action and then cleared out.
     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
  7. 方式4 Flash提供了一种在操作之间传递临时对象的方法。你放在闪光灯中的任何东西都会暴露在下一个动作中然后被清除。  def new    @test_suite_run = TestSuiteRun.new    @tests = Test.find(:all,:conditions => {:test_suite_id => params [:number]})    flash [:someval] = params [:number]  结束  def创建    @test_suite_run = TestSuiteRun.new(params [:test_suite_run])    @tests = Test.find(:all,:conditions => {:test_suite_id => flash [:someval]})  结束

  8. way 5
    you can use rails cache.

    方式5你可以使用rails cache。

      Rails.cache.write("list",[1,2,3])
      Rails.cache.read("list")
    
    But what happens when different sessions have different values? Unless you ensure the uniqueness of the list name across the session this solution will fail during concurrent requests

  9. way 6
    In one action store the value in db table based on the session id and other action can retrieve it from db based on session id.

    方式6在一个操作存储中,基于会话ID和其他操作的db表中的值可以根据会话ID从db检索它。

  10. way 7

    class BarsController < UsersController
    before_filter :init_foo_list

    def method1 render :method2 end

    def方法1      渲染:方法2    结束

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

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

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

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

  11. way 8
    From action sent to view and again from view sent to other actions in controller.

    方式8从发送到视图的动作再次从视图发送到控制器中的其他动作。

#1


21  

It is not a good idea to assign the object to a constant. True this is in a global space, but it is global for everyone so any other user going to this request will get this object. There are a few solutions to this.

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

I am assuming you have a multi-step form you are going through. In that case you can pass the set attributes as hidden fields.

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

<%= f.hidden_field :name %>

If there are a lot of fields this can be tedious so you may want to loop through the params[...] hash or column_names method to determine which attributes to pass.

如果有很多字段,这可能很乏味,因此您可能需要循环使用params [...] hash或column_names方法来确定要传递的属性。

Alternatively you can store attributes in the 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

Thirdly, as Paul Keeble mentioned you can save the model to the database but mark it as incomplete. You may want to use a state machine for this.

第三,正如Paul Keeble所提到的,您可以将模型保存到数据库中,但将其标记为不完整。您可能希望使用状态机。

Finally, you may want to take a look at the Acts As Wizard plugin.

最后,您可能需要查看Acts As Wizard插件。

#2


2  

I usually don't have my controllers calling each other's actions. If you have an identifier that starts with a capital letter, in Ruby that is a constant. If you want to an instance level variable, have it start with @.

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

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

Can you explain what your goal is?

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

#3


2  

Have you considered using the flash hash? A lot of people use it solely for error messages and the like, it's explicitly for the sort of transient data passing you might be interested in.

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

Basically, the flash method returns a hash. Any value you assign to a key in the hash will be available to the next action, but then it's gone. So:

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

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

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

#4


2  

  1. way 1
    Global variable (fail during concurrent requests)
  2. 方式1全局变量(并发请求期间失败)

  3. way 2
    class variable (fail during concurrent requests)
  4. 方式2类变量(并发请求期间失败)

  5. way 3

    • Stash the object on the server between requests. The typical way is to save it in the session, since it automatically serializes/deserializes the object for you.
    • 在请求之间存储服务器上的对象。典型的方法是将其保存在会话中,因为它会自动为您对序列化/反序列化对象。

    • Serialize the object and include it in the form somewhere, and deserialize it from the parameters in the next request. so you can store attributes in the 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
      
  6. way 4
    The flash provides a way to pass temporary objects between actions. Anything you place in the flash will be exposed to the very next action and then cleared out.
     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
  7. 方式4 Flash提供了一种在操作之间传递临时对象的方法。你放在闪光灯中的任何东西都会暴露在下一个动作中然后被清除。  def new    @test_suite_run = TestSuiteRun.new    @tests = Test.find(:all,:conditions => {:test_suite_id => params [:number]})    flash [:someval] = params [:number]  结束  def创建    @test_suite_run = TestSuiteRun.new(params [:test_suite_run])    @tests = Test.find(:all,:conditions => {:test_suite_id => flash [:someval]})  结束

  8. way 5
    you can use rails cache.

    方式5你可以使用rails cache。

      Rails.cache.write("list",[1,2,3])
      Rails.cache.read("list")
    
    But what happens when different sessions have different values? Unless you ensure the uniqueness of the list name across the session this solution will fail during concurrent requests

  9. way 6
    In one action store the value in db table based on the session id and other action can retrieve it from db based on session id.

    方式6在一个操作存储中,基于会话ID和其他操作的db表中的值可以根据会话ID从db检索它。

  10. way 7

    class BarsController < UsersController
    before_filter :init_foo_list

    def method1 render :method2 end

    def方法1      渲染:方法2    结束

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

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

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

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

  11. way 8
    From action sent to view and again from view sent to other actions in controller.

    方式8从发送到视图的动作再次从视图发送到控制器中的其他动作。