2013-04-05 39 views
0

我想用link_to按鈕調用2個不同的動作。當我放置下面的代碼時,該按鈕僅顯示爲藍色鏈接,第二個操作未被調用。有人知道一個策略來解決這個問題嗎?用link_to按鈕在2個不同的控制器上調用動作

<%= link_to "Remove from Cabinet", { :controller => 'devices', :action => 'detach_device_from_cabinet', :id => device.id }, 
      { :controller => 'cabinets', :action => 'unmark_validated', :id => @cabinet.id }, :class => "btn btn-danger", :confirm => "Detach Device: are you sure?" %> 

謝謝。

回答

4

從單個link_to調用多個控制器操作並不是一個好習慣。你爲視圖添加了太多的邏輯。

有一個叫「胖模型,瘦控制器」軌道的設計模式。您希望在模型中完成所有業務邏輯,並且只需調用模型的方法即可。在這個具體的例子中,你想從一個機櫃中分離設備,每個設備可以在一個機櫃上,每個機櫃可以容納多個設備。

我沒有檢查這個代碼,但你想要的東西應該是接近:

cabinet.rb

class Cabinet < ActiveRecord::Base 
    has_many :devices 
    ... 

    def self.detach_device(id) 
    cabinet = Cabinet.where(device: id).first 
    cabinet.devices.drop(id) 
    cabinet.unmark_validated 
    end 

    def unmark_validated 
    cabinet.marked == false 
    end 
end 

device.rb

class Device < ActiveRecord::Base 
    belongs_to :cabinet 
    ... 

end 

cabinets_controller.rb

class CabinetsController < ApplicationController 
    def detach_from_cabinet 
    @cabinet = Cabinet.detach_device(params[id]) 

    end 
end 

<%= link_to "Remove from Cabinet", :controller => 'cabinets', :action => 'detach_device', id => device.id %>

+0

感謝胖/瘦類比。這有助於我更多地理解架構。那麼什麼是幫手? – 2013-04-05 20:00:32

+0

助手允許您將代碼保留在視圖之外。一些常見的助手是'link_to''' button_to'''form_for'。如果你還不熟悉,railscasts.com是一個很好的資源,很多rails開發人員經常使用。 – John 2013-04-05 20:33:32

0

我從未想過在此之前,我不明白的邏輯,但你應該做重構... ...打電話的動作,發送數據,而且動作可以調用執行您想要其他的東西給一個函數做。另外,你應該使用別名,在路由中定義它。

0

也有類似的情況,我需要用戶在一個模型視圖按下一個按鈕,並在不同的型號的控制器創建一個新的行,然後同時更改源模型中的布爾屬性。我最終削弱了我的控制器,並在相應的模型中創建了一個新方法,並在動作中指向它。在@ John的回答中捎帶,這裏是對我有用的,可能是一個替代的策略,或者需要在一個用戶按下按鈕時執行多個動作的任何人,並且可能在多個模型之間執行:

FOO CONTROLLER /新

def new 
    ... 
    # After button is pushed sending params to this action, thusly 
    # creating the new row, and saving it 
    @foo.save 
    # Then to the newly created method 
    @foo.new_method 
    # and back for a redirect 
    redirect_to :foos, notice: "..." 
    end 

foo.rb

def new_method 
    @bar = Bar.find_by(:attribute => true) 
    # Simply need to fllip attribute from true to false 
    if @bar.attribute == true 
     @bar.attribute = false 
    end 
    @bar.save 
    end 
相關問題