2013-08-29 68 views
0

我正在显示我的视图中的项目列表。我的控制器类执行一个SQL来获取列表。此外,我更新表中的一些值,如果取回列表。问题是在select语句之前正在设置值。下面是控制器的代码:Ruby中的SQL命令执行顺序

@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中更新了值。有什么办法可以让我选择后执行更新语句。我尝试了下面和其他选项,但没有运气。

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

请指教。谢谢。

回答

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::paginate_array

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

请注意,在Rails 3中,还可以使用.all方法(如在List.select().where().all中)来执行和评估查询。然而,在轨道4,5,Model.all现在等效Model.scoped并懒洋洋地评估,因此,.to_a


或者,你可能想看看ActiveRecord::Relation#load方法:

原因记录为如果它们尚未加载,则从数据库加载。 如果由于某种原因需要在实际使用 之前明确加载一些记录,则可以使用此选项。返回值是关系本身,而不是记录。

无可否认,我从来没有真正使用过,但在这种情况下它可能更合适。

+0

非常感谢。 .to_a工作。我的查询将有最多10行,所以表现明智,这不是一个问题。再次感谢您的详细解释。这有很大帮助。 – Gaurav