【问题标题】:Active Record class活动记录类
【发布时间】:2013-07-14 10:16:51
【问题描述】:

我正在做一个迁移项目。想要将 rails 2.x 应用程序迁移到 3.x。我的活动记录有问题。

在 Rails 2.x 中:

arr=StorageUnit.find(:all, :conditions =>"type='Drawer'")

上面的代码会得到所有类型为 Drawer 的记录。

arr.class
=> Array

在 Rails 3.x 中:

这里不推荐使用上述功能。所以我不得不使用

arr=StorageUnit.where("type='Drawer'")

上面的代码会得到所有类型为 Drawer 的记录。

arr.class
ActiveRecord::Relation

我猜这是因为 Active Record 发生了变化。 我的问题是我有一些基于此类的代码。

例如:

if arr.class== Array 
   do something
else
   do something
end

所以现在我把它改成了

if arr.class== ActiveRecord::Relation 
   do something
else
   do something
end

只是想知道是否有更好的解决方案或任何替代方法来解决它。我有很多地方他们用过这种东西。

编辑:

arr=StorageUnit.where("type='Drawer'").all

将类提供为数组。我的目标是知道什么时候没有后缀的代码可以提供你需要的记录,而不是全部到底有什么用。?只是为了换班吗?谁能解释一下?

【问题讨论】:

  • 显式检查事物的类别并不是非常地道的红宝石
  • @FrederickCheung 是正确的。如果需要绝对查类,可以使用arr.is_a?(Array)

标签: ruby ruby-on-rails-3 activerecord


【解决方案1】:

StorageUnit.where 只返回ActiveRecord 关系。加入.all 将执行sql 并创建StorageUnit 的实例。

arr = StorageUnit.where(:type => 'Drawer').all

它作为关系返回有许多有趣的副作用。除其他外,您可以在执行之前组合范围:

StorageUnit.where(:type => 'Drawer').where(:color => 'black')

您可以查看生成的sql进行调试:

StorageUnit.where(:type => 'Drawer').to_sql

想象一下:

class StorageUnit < ActiveRecord::Base

  scope :with_drawer, where(:type => 'Drawer')
  scope :with_color, lambda { |c| where(:color => c) }

end

现在:

StorageUnit.with_drawer.with_color('black').first_or_create # return the first storage unit with a black drawer
StorageUnit.with_drawer.with_color('black').all # return all storage units with black drawers

该关系允许构建基础查询,甚至可以保存以供以后使用。 all等修饰符对关系有特殊意义,触发数据库执行和模型实例的构建。

【讨论】:

  • 我知道在这种情况下该类将是 Array 但我有一个问题。当没有 all 的代码可以获得所需的记录时,比指定 all 有什么用。两者都给出相同的结果仪式..?但不同的类别。
  • with_drawer 不需要是 lambda,只要没有 lambda 包装器的 where(:type =&gt; 'Drawer') 就可以了; with_color 应该是一个类方法,因为"Using a class method is the preferred way to accept arguments for scopes"。只是挑剔:)
  • 我不知道 Rails 推荐使用类方法而不是作用域。你知道为什么它比范围更受欢迎吗,@muistooshort?我相信它们几乎是一样的。
  • @AmarnathKrishnan all 在 Rails 3 和 to_a 在 Rails 4 为您运行查询。有时您希望查询在指定时间运行,而不是在真正需要时运行。
  • @PedroNascimento:我猜这是因为类方法(例如where)已经存在,所以不需要 lambda,但这只是一个疯狂的猜测。
猜你喜欢
  • 1970-01-01
  • 2012-06-14
  • 2014-08-15
  • 1970-01-01
  • 1970-01-01
  • 2014-02-22
  • 1970-01-01
  • 1970-01-01
  • 2012-07-22
相关资源
最近更新 更多