我在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'权限的人。)我应该:添加一个发布到新创建的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
添加提交执行相同控制器代码的form_for?
在Wall模型中添加一个新方法来处理这个问题吗?
我可能会过度思考这个问题,但是在我遇到一条过于复杂的道路之前,我会感激一些方向,这会导致将来出现问题。
答案 0 :(得分:2)
由于您不需要将任何数据传递给服务器而不是URL中的ID,因此使用link_to
应该没问题。
当您更改服务器上的数据时,使用:method => :post
使此方法POST - 在没有POST的情况下更改数据是一个坏主意
如果您不需要特殊视图,还可以使用:remote => true
使用AJAX将表单提交到此URL。否则,您问题中的redirect_to
就足够了。
有关如何构建link_to
然后我会直接在控制器中实现逻辑(如下所示)
使用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)