Ruby on rails 检查Rails中是否加载了sql对象
我的模型:Ruby on rails 检查Rails中是否加载了sql对象,ruby-on-rails,activerecord,preload,Ruby On Rails,Activerecord,Preload,我的模型: class User has_many :items end class Item belongs_to :user def self.with_color(color, is_loaded) if is_loaded self.select { |i| i.color == color } else self.where(:color => color) end end end 我的控制器中有两种类型的代
class User
has_many :items
end
class Item
belongs_to :user
def self.with_color(color, is_loaded)
if is_loaded
self.select { |i| i.color == color }
else
self.where(:color => color)
end
end
end
我的控制器中有两种类型的代码
## this line loads 'items' of the user and selects with the red color ##
@colored_items = current_user.items.with_color('red', false)
## this code should not load items twice ##
@user_with_items = User.includes(:items).find(params[:user_id])
(...)
colored_items = @user_with_items.with_color('red', true)
如果我只写选择版本,它不适用于1个示例,“where”版本再次加载项目,即使它们已经加载
如何检查对象是否已加载?如何使用作用域 例如:
class Shirt < ActiveRecord::Base
scope :colored, lambda { |color| where(:color => color) }
end
更新:
class User < ActiveRecord::Base
has_many :items
def colored_items(color)
self.items.to_a.select { |i| i.color == color }
end
end
user = User.includes(:items).find(1)
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
Item Load (0.4ms) SELECT "items".* FROM "items" WHERE "items"."user_id" IN (1)
=> #<User id: 1, name: nil, created_at: "2012-03-25 00:39:52", updated_at: "2012-03-25 00:39:52">
user.colored_items "red"
=> [#<Item id: 1, color: "red", user_id: 1, created_at: "2012-03-25 00:41:00", updated_at: "2012-03-25 00:41:00">]
user.colored_items "blue"
=> [#<Item id: 2, color: "blue", user_id: 1, created_at: "2012-03-25 00:41:04", updated_at: "2012-03-25 00:41:04">]
所以这里只有2个SQL。Scope与self.colored的方法相同。第一个示例运行良好,但第二个示例将执行另一个查询,以仅加载“红色”项。我会使用@users_with_items.items.select{| e | e.color=='red'}而不是scope来使用已经加载的对象。好的,你说得对。Scope每次都在执行SQL。我想它会处理好的。可能是可以优化的东西。所以我在上面的答案中添加了一个可能的解决方案。谢谢-。正是我需要的。
class User < ActiveRecord::Base
has_many :items
def colored_items(color)
self.items.to_a.select { |i| i.color == color }
end
end
user = User.includes(:items).find(1)
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
Item Load (0.4ms) SELECT "items".* FROM "items" WHERE "items"."user_id" IN (1)
=> #<User id: 1, name: nil, created_at: "2012-03-25 00:39:52", updated_at: "2012-03-25 00:39:52">
user.colored_items "red"
=> [#<Item id: 1, color: "red", user_id: 1, created_at: "2012-03-25 00:41:00", updated_at: "2012-03-25 00:41:00">]
user.colored_items "blue"
=> [#<Item id: 2, color: "blue", user_id: 1, created_at: "2012-03-25 00:41:04", updated_at: "2012-03-25 00:41:04">]