简体   繁体   English

实际上,如何从Rails中的控制器调用控制器?

[英]How can I, in effect, call a controller from a controller in Rails?

Ok, ok, on the surface this seems like a very bad idea, and most of the time it is. 好吧,好吧,从表面上看,这似乎是一个非常糟糕的主意,并且在大多数情况下是这样。 It is not MVC, it creates potential weird dependencies, and it does not follow good logical separation of concerns. 它不是MVC,它会创建潜在的奇怪依赖关系,并且不会遵循良好的逻辑分离关注点。

Now let me explain the situation that has led me to ask this question. 现在让我解释一下导致我问这个问题的情况。 We have a third party api. 我们有第三方api。 We necessarily have to cache it for long periods of time for performance reasons. 出于性能原因,我们必须将其长时间缓存。 Sometimes they change their data, and we need reflect it immediately. 有时他们会更改数据,我们需要立即对其进行反映。 We have given them an api endpoint to clear the cache (as we are not going to give them access to our internal cache, for a variety of reasons). 我们为他们提供了一个api端点来清除缓存(由于各种原因,我们不会让他们访问我们的内部缓存)。 I need some way to rewarm the cache. 我需要某种方式重新缓存。 Rewarming their api call is easy. 刷新他们的api调用很容易。 However, we have view fragment caches that are dependent on that data, and I would like to rewarm those as well. 但是,我们有依赖于该数据的视图片段缓存,我也想重新包装它们。

Basically I would like to cache everything that would normally be cached during a call on this second controller. 基本上,我想缓存在此第二个控制器上调用期间通常会缓存的所有内容。 However, trying this results in timeouts on the second controller call. 但是,尝试执行此操作将导致第二个控制器调用超时。 Is there a way to accomplish this, or an alternate method that will result in all necessary elements (including view elements that use rails fragment caching) to be cached? 有没有办法做到这一点,或者有一种替代方法会导致所有必需的元素(包括使用rails片段缓存的视图元素)被缓存?

It seems like your real problem is busting the fragment caches. 看来您真正的问题是破坏片段缓存。 Why not just use a self busting cache key. 为什么不只使用自我破坏缓存键。 If you're caching a piece of the view with cache 'key' do... that "key" string could be updated by a model or something such as the Post.count or something. 如果您要使用cache 'key' do...视图, cache 'key' do...该“ key”字符串可以由模型或诸如Post.count东西来更新。 For example, in an API controller caching a list of Posts as a JSON list: 例如,在API控制器中,将帖子列表作为JSON列表缓存:

# your api controller's index action
@post_json = Rails.cache.fetch "posts-#{Post.count}-#{Post.order(:updated_at).last.updated_at}" do
  Post.all.to_json
end

Now that you have a collection of posts cached and ready to be sent as an API response and you're using a self busting cache key you won't have to worry about manually "rewarming" your cache. 现在,您已经缓存了一组帖子,并准备好作为API响应发送,并且您正在使用自失效缓存键,您不必担心手动“重新武装”您的缓存。 Whenever a new Post is created or one is updated the cache key will be different because the count and updated_at (for the most recently updated post) will be different and cause the Rails.cache.fetch method to execute the block, rewarming your cache. 每当创建一个新帖子或更新一个新帖子时,缓存键都会不同,因为countupdated_at (对于最近更新的帖子)将不同,并且会导致Rails.cache.fetch方法执行该块,从而重新设置缓存。

With this sort of dynamic cache key you can use any method to update it that doesn't require calling a controller (which is very hard and not recommended). 使用这种动态缓存键,您可以使用任何不需要调用控制器的方法来对其进行更新(这很困难,因此不建议使用)。

To get around the problem of Rails maintaining a single connection, you can use a multi-threaded approach: 要解决Rails维护单个连接的问题,可以使用多线程方法:

Thread.new do
    # do stuff here
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM