Ruby中的SQL命令执行序列

时间:2013-08-29 09:54:51

标签: ruby-on-rails ruby

我在我的视图中显示了一个项目列表。我的控制器类执行一个sql以获取列表。如果获取列表,我也会更新表中的一些值。问题是在select语句之前设置了值。以下是控制器代码:

@orders = List.select("itemname,tableno,quantity,itmstatus").where(:tableno => "01")
List.where(:tableno => "01").update_all(:ordstatus => 'displayed',:itmstatus => 'displayed')

我的视图显示@orders中检索到的不同字段。现在基于itemstatus值我需要在视图中设置文本颜色代码。因此,一旦执行了我的select语句,我就将itmstatus值设置为其他值。但在我看来,@ orders有更新的值(我在选择后正在做)。我检查了服务器端,并且在更新语句之后执行了select语句,我认为可能是在@orders中具有更新值的情况。有什么方法可以让我在select之后执行update语句。我在下面尝试了几个其他选项,但没有运气。

if @orders
 @orders = List.select("itemname,tableno,quantity,itmstatus").where(:tableno => "01")
 List.where(:tableno => "01").update_all(:ordstatus => 'displayed',:itmstatus => 'displayed')
end

请指教。感谢。

1 个答案:

答案 0 :(得分:2)

当视图枚举@orders = List.select("itemname,tableno,quantity,itmstatus").where(:tableno => "01")实例变量时,代码@orders延迟评估。也就是说,它是ActiveRecord::Relation,只有在渲染视图时才真正得到评估(SQL执行)。

阻止此操作的一种方法是在以后更新语句之前完全执行查询并检索所有行,即在to_a上调用ActiveRecord::Relation

@orders = List.select(...).where(...).to_a

要注意的一件事是,如果你使用Kaminari进行分页,那么常规的Kaminari分页扩展将无效 - 你必须使用Kaminari::paginate_array

另一件需要考虑的事情是,如果您的查询可能会返回大量记录。通过调用to_a,您告诉ActiveRecord一次性将所有这些记录检索到内存中,这会降低性能。

请注意,在Rails 3中,还可以使用.all方法(如List.select().where().all)来执行和评估查询。但是,在Rails 4中,Model.all现在等同于Model.scoped,并且会进行延迟评估,因此,.to_a


或者,您可能希望查看ActiveRecord::Relation#load方法:

  

如果尚未加载记录,则会从数据库加载记录。   如果出于某种原因需要在之前显式加载某些记录,则可以使用此方法   实际上使用它们。返回值是关系本身,而不是记录。

不可否认,我从未真正使用过,但在这种情况下可能更合适。