Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/53.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 缓存有限关联_Ruby On Rails_Ruby On Rails 3_Caching_Activerecord - Fatal编程技术网

Ruby on rails 缓存有限关联

Ruby on rails 缓存有限关联,ruby-on-rails,ruby-on-rails-3,caching,activerecord,Ruby On Rails,Ruby On Rails 3,Caching,Activerecord,我正在尝试缓存具有关联的ActiveRecord。问题是,在访问检索到的记录上的关联时,存在数据库查询 通常情况下,我只需要使用渴望加载的Rails.cache.write'post',post.includes:comments.find99进行缓存。这似乎是可行的,但问题是我只想缓存有限的关联子集,例如,当提到急切加载时,限制被忽略。因此Post.includes:popular_comments.find99将返回所有评论,而不仅仅是流行的评论 因此,我尝试在延迟加载关联后缓存对象,但不幸

我正在尝试缓存具有关联的ActiveRecord。问题是,在访问检索到的记录上的关联时,存在数据库查询

通常情况下,我只需要使用渴望加载的Rails.cache.write'post',post.includes:comments.find99进行缓存。这似乎是可行的,但问题是我只想缓存有限的关联子集,例如,当提到急切加载时,限制被忽略。因此Post.includes:popular_comments.find99将返回所有评论,而不仅仅是流行的评论

因此,我尝试在延迟加载关联后缓存对象,但不幸的是,在拉出对象时会发生查询:

class Post < ActiveRecord::Base
  has_many :comments
  has_many :popular_comments, :class_name > 'Comment', :limit => 20, :order => :votes

post = Post.find(99)
post.popular_comments # lazy-load limited associations
Rails.cache.write('post', post)
...
Rails.cache.read('post').popular_comments # Unwanted SQL query :(
我试着缓存一个克隆,同样是不需要的SQL查询。我在redis和memcached实现中都尝试过,结果是一样的。奇怪的是,这个序列确实在控制台afaict上起作用,但是在上面这样的控制器或视图中使用简单的方法就失败了


2017年4月更新:我现在想说这是一个愚蠢的前提。缓存整个对象通常是浪费的,因为它使用了大量缓存存储,并且序列化/反序列化它们的速度很慢。缓存关联以及本问题中提出的问题是将损耗乘以N。通常,只缓存原始ID和HTML片段更有效。

我没有看到您在测试中描述的问题

我在控制器中使用的代码

def show
  unless Rails.cache.exist?('faq_category')
    @faq_category = Faq::Category.first
    @faq_category.questions
    Rails.cache.write('faq_category', @faq_category)
  end
  @faq_category = Rails.cache.read('faq_category')
end
当我运行该页面时,我在日志中看到以下语句,表示模型没有被重新加载 大图可于

问题可能在于您的视图文件。评论视图,看看问题是否仍然存在。

尝试post.popular\u comments.reload

首先,在快速加载时,实际上忽略了限制。发件人:

如果使用指定的:limit选项加载关联,将忽略该关联,并返回所有关联对象

这意味着,正如您所发现的,您必须自己将关联强制到父对象中。在我的实验中,post.popular_comments不起作用,因为它返回一个代理对象,有趣的是post.popular_comments.all也不起作用。然而,post.popular_commentstrue起了作用。在该代码下面调用reload,只需执行post.popular_comments.reload,就可以将关联加载到父类中

我不确定这两个选项中哪一个更正确,post.popular\u commentstrue还是post.popular\u comments.reload。两者似乎都有点脆弱,但第二个读起来更好,表达你的意图更清楚

我验证了这两种方法:

将有限关联存储在memcache中 从缓存加载后未触发SQL查询 存储帖子的脚本:

require 'pp'
Rails.cache.clear
post = Post.first

#post.popular_comments(true)
post.popular_comments.reload

Rails.logger.info "writing to cache"
s = Rails.cache.write "post", post
Rails.logger.info "writing to cache done"
以及检索:

require 'pp'
Rails.logger.info "reading from cache"
post = Rails.cache.read "post"
Rails.logger.info "reading from cache done"
Rails.logger.info post.popular_comments.inspect
如果我一个接一个地运行,我的日志会显示:

  Post Load (0.5ms)  SELECT `posts`.* FROM `posts` LIMIT 1
  Comment Load (0.5ms)  SELECT `comments`.* FROM `comments` WHERE `comments`.`post_id` = 1 ORDER BY votes LIMIT 20
writing to cache
writing to cache done
reading from cache
reading from cache done
[#<Comment id: 1, ...
我的mySQL日志还确认第二个脚本不会触发关联查询

这是通过Rails 3.1.1实现的,Rails 5根本不支持:limit=>20选项。您将得到以下错误:

ArgumentError:未知键::限制。有效键为::class_name, :匿名\u类、:外部\u键、:验证、:自动保存、:表\u名称、, :添加前,:添加后,:删除前,:删除后,:扩展, :主键,:从属,:as,:至,:源,:源类型, :反向的,:计数器缓存,:联接表,:外部类型,:索引错误


你必须明确地使用post.popular\u comments.limit20。

这是我看到的一个问题,很多关联都是有限的。我在问题中添加了更多信息。当我有时间的时候,我会尝试模拟你的情况。非常感谢。事情不应该那么复杂。只有一个与定义在关联上的限制有很多关联。您正在运行哪个版本的Rails?@Brandan这是在Rails 3.1上。您可以发布一个日志片段,精确显示SQL正在执行的内容以及在请求中发生的位置吗?我无法复制它。@Brandan现在没有这个确切的代码,但我会看看是否可以用一个虚拟项目复制它。你的Rails版本是什么?我在我的设置中尝试了这个,它对我有效。很好,回答,谢谢。我现在不能测试它,但是你已经理解了这个问题,这听起来是最好的解决方案。