2011-11-08 28 views
1

我在Rails的一個非常標準的CRUD應用& jQuery Mobile的有兩個型號有關我的問題:如何將方法添加到更新對象集合的Rails應用程序?

class Wall < ActiveRecord::Base 
    has_many :problems 
end 

class Problem < ActiveRecord::Base 
    # boolean attribute is_live 
    belongs_to :wall 
end 

當顯示每個牆,我抓住每一個問題屬於該牆這is_live ==真。我現在的目標是創建一種方法,通過在is_live == true的情況下查找牆上的每個問題並更新is_live爲false來「清除」所有問題的牆。

但是,我不知道找到並更新每個適當對象的最佳做法/方法。 (這將是隻提供給那些具有「管理」權限的限制功能。)我應該:

  1. 添加的link_to該職位到新創建的WallController行動 像下面?

    def clear_wall 
        @wall = Wall.find(params[:id]) 
        @problems = @wall.problems.where(:is_live => true) 
        @problem.each {|p| p.update_attribute(:is_live => false) } 
    
        redirect_to(walls_url) 
    end 
    
  2. 添加form_for提交執行相同的控制器代碼?

  3. 在Wall模型中添加一個新方法來處理這個問題?

我得太多可能這個漂亮的沉重,但我會很感激一些方向之前,我失足落下一個過於複雜的道路,導致在未來的問題。

回答

2

由於您不需要將任何數據傳遞到除URL中的ID以外的任何數據,因此使用link_to應該沒問題。

請使用:method => :post,你在服務器上改變數據這種方法POST - 變化的數據,而無需繳納是一個壞主意

如果你不需要特殊的視圖,你也可以使用:remote => true使用Ajax提交一個表單到這個URL。否則,您的問題中的redirect_to就足夠了。

ActionView文檔瞭解如何建設更多信息您link_to

話,我會實現邏輯(如下)在你的控制器直接

使用update_all在DB更新許多對象

的ActiveRecord有update_all方法,你可以在一個ActiveRecord::Relation

調用

它不是load the models from the DB, or call callbacks但是因爲將任何不是假的設置爲false在功能上等同於將所有設置爲false,因此可能會適合您的目的。

Wall.find(params[:id]).problems.update_all(:is_live => false)

你可以提供一個條件參數,以update_all

Wall.find(params[:id]).problems.update_all(:is_live => false, "is_live = true")

或交替進行,其中第一,但首先會加載所有從數據庫中的數據,並在你的情況,似乎不必要。這裏要注意的重要一點,就是update_all方法適用於ActiveRecord::Relation而不是ActiveRecord::Base

Wall.find(params[:id]).problems.where(:is_live => true).update_all(:is_live => false)

+0

艾瑪,指着我對update_all是超級有用的,看起來像執行更新更清潔的方式,但我實際上我們也不確定如何構建視圖來處理這個問題。 link_to與form_for,它應該是一個POST還是一個PUT等等。 – IanWhalen

+0

@IanWhalen我已經更新了我的答案(幾次!),所以希望它對現實中的問題更有意義。 – Emma

+2

類似'link_to「Clear Wall」,clear_wall_url(@ wall.id),:method =>:post' –

相關問題