abe*_*ger 9 ruby-on-rails-3 rails-activerecord
我在Rails 3中工作并且有一个包含多个子表的表,例如
class Foo < ActiveRecord::Base
has_many :things
has_many :items
has_many :widgets
end
class Thing < ActiveRecord::Base
belongs_to :foo
end
class Item < ActiveRecord::Base
belongs_to :foo
end
class Widget < ActiveRecord::Base
belongs_to :foo
end
Run Code Online (Sandbox Code Playgroud)
有一种简单的方法让我检查给定的Foo是否在一个或多个表中有子记录?基本上,有更好的方法来做到这一点:
if !foo.things.empty? or !foo.items.empty? or !foo.widgets.empty?
puts "This foo is in use!"
emd
Run Code Online (Sandbox Code Playgroud)
嗯,我认为你走的是正确的轨道,但也许只是把它作为你的Foo模型中的一种方法
class Foo < ActiveRecord::Base
def children?
things.any? || items.any? || widgets.any?
end
end
Run Code Online (Sandbox Code Playgroud)
然后只是说,Foo.first.children?并获得true当富实例有任何孩子.
这any?是为了什么.
class Foo < ActiveRecord::Base
def children?
things.any? || items.any? || widgets.any?
end
end
Run Code Online (Sandbox Code Playgroud)
由于这已成为争论的话题,我向您呈现:
> foo = Foo.last
Foo Load (0.6ms) SELECT "foos"......
> foo.items
Item Load (0.9ms) SELECT "items".*.......
> foo.items.any?
=> true #OH, WHAT's that? NO SQL CALLS? GEE WILLICKERS
> foo.items.exists?
Item Exists (0.5ms) #Hmmmmmm....
=> true
Run Code Online (Sandbox Code Playgroud)
这里的要点是,在任何情况下,如果总是加载到内存中,exists则进行数据库调用,any?而不进行数组调用spaces.正如我所说,很多时候,重要的不是数据库调用的效率(AND YES,SQL调用exists?使效率更高),但事实上any?不一定会调用DB,这是一个巨大的优点.找你自己:
[20] pry(main)> Benchmark.measure { foo.item.exists? }
Item Exists (0.5ms) SELECT 1 AS one FROM "items" ...
=> #<Benchmark::Tms:0x007fc1f28a8638
@cstime=0.0,
@cutime=0.0,
@label="",
@real=0.002927,
@stime=0.0,
@total=0.00999999999999801,
@utime=0.00999999999999801>
[21] pry(main)> Benchmark.measure { foo.items.any? }
=> #<Benchmark::Tms:0x007fc1f29d1aa0
@cstime=0.0,
@cutime=0.0,
@label="",
@real=7.6e-05,
@stime=0.0,
@total=0.0,
@utime=0.0>
Run Code Online (Sandbox Code Playgroud)
有关更简洁的时间,请查看以下内容:
> Benchmark.measure { 1000.times {foo.items.exists?} }.total
=> 2.5299999999999994
> Benchmark.measure { 1000.times {foo.items.any?} }.total
=> 0.0
Run Code Online (Sandbox Code Playgroud)
就像我说的那样,很多时候,它取决于环境 - 你可能有很多情况下这些物品没有加载到内存中,但很多时候,它们都是.根据您的调用方式,选择最适合您的方法.
这应该适用于任何给定的模型。
class Foo < ActiveRecord::Base
def children?
has_associated_records = self.class.reflect_on_all_associations.map { |a| self.send(a.name).any? }
has_associated_records.include?(true)
end
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3077 次 |
| 最近记录: |