如何将方法添加到更新对象集合的Rails应用程序?

时间:2011-11-08 19:46:24

标签: ruby-on-rails jquery-mobile rails-activerecord

我在Rails& amp;中有一个非常标准的CRUD应用程序。 Jquery Mobile有两个与我的问题相关的模型:

class Wall < ActiveRecord::Base
  has_many   :problems
end

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

当显示每个墙时,我抓住属于该墙的每个问题,其中is_live == true。我现在的目标是创建一种方法,通过使用is_live == true查找墙上的每个问题并将is_live更新为false来“清除”所有问题的墙。

但是,我不知道查找和更新每个适当对象的最佳实践/方法。 (这将是一个限制功能,仅适用于具有'admin'权限的人。)我应该:

  1. 添加一个发布到新创建的WallController操作的link_to 如下?

    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模型中添加一个新方法来处理这个问题吗?

  4. 我可能会过度思考这个问题,但是在我遇到一条过于复杂的道路之前,我会感激一些方向,这会导致将来出现问题。

1 个答案:

答案 0 :(得分:2)

由于您不需要将任何数据传递给服务器而不是URL中的ID,因此使用link_to应该没问题。

当您更改服务器上的数据时,使用:method => :post使此方法POST - 在没有POST的情况下更改数据是一个坏主意

如果您不需要特殊视图,还可以使用:remote => true使用AJAX将表单提交到此URL。否则,您问题中的redirect_to就足够了。

有关如何构建link_to

的详细信息,请参阅ActionView文档

然后我会直接在控制器中实现逻辑(如下所示)

使用update_all更新数据库中的许多对象

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")

或者首先执行where,但这将首先从DB加载所有数据,在您的情况下似乎没有必要。这里要注意的重要一点是,update_all方法适用于ActiveRecord::Relation而非ActiveRecord::Base

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