Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>So I've tried a number of different approaches, to see what works, and what doesn't.</p> <p>Again, to summarize the situation: <strong>My goal is to expire cached pages when an object updates, but to expire them without relying on a Controller action.</strong> Conventional sweepers use a line in the controller to notify the sweeper that it needs to function. In this case, I can't use a line in the controller, as the update is happening within the model. Normal sweeper tutorials aren't working, as they presume that your main interaction with the database object is through the controller.</p> <p>If, in reading this, you see a way to tighten up my code, please comment and let me know.</p> <p>First, let's look at the things that DO work, in case you're stuck on this, too, and need help.</p> <p>Of all the things I tried, the only thing that really seemed to work was to declare an after_update command in the Observer for the model. In that command, I used the explicit command for the expire_page action, and included a path that had been declared in routes.rb.</p> <p>So. This works:</p> <p>In config/routes.rb:</p> <pre><code>map.link 'l/:md5.:format', :controller =&gt; 'links', :action =&gt; 'show' </code></pre> <p>In app/models/link_observer.rb:</p> <pre><code>def after_update(link) ActionController::Base.expire_page(app.link_path(:md5 =&gt; link.md5)) end </code></pre> <p>Note that that "md5" is specific to my app. You might want to use :id or some other unique identifier.</p> <p>I also found that declaring that ActionController::Base... line from the method in the model that's doing the updating worked. That is, within Link.rb, in the method that's actually updating the database, if I just stuck that whole line in, it worked. But since I might want to expire that page cache on other methods in the future, I'd rather have it extracted into the Observer.</p> <p>Now, let's look at some things that DID NOT work, in case you're Googling around for this.</p> <p><strong>Calling "expire_page(...)"</strong> within the after_update(link) method within link_observer.rb did not work, as it returned an "undefined method `expire_page'" error</p> <p><strong>Creating a Sweeper file</strong> that observed the Model did not work. I couldn't find any error codes, but it just seemed to not even be aware that it had a job to do. This was after explicitly calling "config.load_paths += %W( #{RAILS_ROOT}/app/sweepers )" within environment.rb. Just in case I fat-fingered something in that code, here it is:</p> <pre><code>class LinkSweeper &lt; ActionController::Caching::Sweeper observe Link def after_update(link) clear_links_cache(link) end def clear_links_cache(link) # DID NOT WORK expire_page :controller =&gt; 'links', :action =&gt; 'show', :md5 =&gt; link.md5 # DID NOT WORK expire_page '/l/'+ link.md5 + '.html' # DID NOT WORK ActionController::Base.expire_page(app.link_path(:md5 =&gt; link.md5)) end end </code></pre> <p>That above example had the link_sweeper.rb file in a directory, /app/sweepers. I also tried putting link_sweeper.rb within the app/models directory, and tried calling it with the config.active_record.observers command in environment.rb:</p> <pre><code>config.active_record.observers = :link_observer, :link_sweeper </code></pre> <p>But that didn't work, either.</p> <p>So, yeah. It's quite possible that one of these methods would work, and that I messed up something in the code. But I think I did everything by the book.</p> <p>Ultimately, to summarize: Rather than using a Sweeper to expire page caching, you want to set up an after_ callback in the model's Observer. You'll want to use the explicit path to the Base.expire_page method:</p> <pre><code>def after_update(&lt;model&gt;) # where &lt;model&gt; is the name of the model you're observing ActionController::Base.expire_page(app.&lt;model&gt;_path(:id =&gt; &lt;model&gt;.id)) # where &lt;model&gt; is the name of the model you're observing end </code></pre> <p>Hopefully this will help someone else down the road. Again, if you see anywhere in my not-working code where I should have done something differently, please let me know. If you see something in my working code that can be tighter, please let me know that, too.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload