2009-08-17 96 views
8

我一直在試圖讓我的頭在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的。基本上是這樣的,你不能將變量從控制器傳遞到控制器?我必須認爲,有某種方式,但我似乎無法找到它。

回答

20

將對象賦給常量不是一個好主意。確實這是在全局空間中,但它對每個人都是全局的,所以任何其他用戶都會收到此請求。有幾個解決方案。

我假設你有一個多步驟的形式,你正在經歷。在這種情況下,您可以將設置屬性作爲隱藏字段傳遞。

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

2

我通常沒有我的控制器調用對方的動作。如果你有一個以大寫字母開頭的標識符,在Ruby中是一個常量。如果你想要一個實例級別的變量,讓它以@開頭。

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

你能解釋一下你的目標是什麼嗎?

+0

從本質上講,我試圖做一個多步驟的過程,其中一個用戶上傳文件,然後我處理它,並重新目前它回給他們,讓他們做出一些改變它,最後將其插入進入數據庫。 要做到這一點,雖然我需要能夠向對象傳遞到另一個控制器或至少另一個控制器視圖。 – 2009-08-17 07:28:10

+0

不是這樣做,爲什麼不是你運作的中間結果存儲在數據庫中,並將它標誌爲未完成。通過這種方式,您知道您可以像平常一樣通過模型訪問它,並且可以適應服務器故障。 – 2009-08-17 12:08:03

2

你有沒有考慮使用閃存散列?很多人只是將它用於錯誤消息等,它明確表示您可能感興趣的那種瞬態數據傳遞。

基本上,flash方法返回一個散列。您分配給散列中的某個鍵的任何值都將可用於下一個操作,但隨後它消失了。所以:

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

def second 
    @hello = flash[:var].first 
end 
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
    閃光燈提供了一種方式來傳遞動作之間的臨時對象。你放在閃光燈中的任何東西都會暴露在下一個動作中,然後被清除。
     
    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
    從動作發送到從視圖發送到控制器的其他操作查看和試。

相關問題