0

我正在我的视图中显示项目列表。我的控制器类执行 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 中更新值的情况。有什么方法可以让我在选择之后执行更新语句。我尝试了下面和其他几个选项,但没有运气。

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

请指教。谢谢。

4

1 回答 1

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方法:

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

诚然,我从未真正使用过它,但在这种情况下它可能更合适。

于 2013-08-29T10:07:03.260 回答