rails4 after caching query still runs

2019-09-19 08:00发布

问题:

I have a rails 4 app and trying to implement caching. I use the @profiles_sidebar.first cache key for checking if new user was created. I'm not sure if this is ok, since there still is a db query. Is this the preferred mechanism to check if caching needs to be expired? Am I doing well?

<% cache(@profiles_sidebar.first) do %>
  <% @profiles_sidebar.each do |profile| %>
    <%= link_to user_path(profile.user) do %>            
      <%= truncate(profile.full_name, length: 25) %>
      <%= truncate(profile.company, length:25) %>
    <% end %>
  <% end %>
<% end %>

console code when reading cache:

13:31:53 puma.1    |   Profile Load (2.2ms)  SELECT  "profiles".* FROM "profiles"  ORDER BY "profiles"."created_at" DESC LIMIT 1
13:31:53 puma.1    |   User Load (2.2ms)  SELECT "users".* FROM "users" WHERE "users"."id" IN (67)
13:31:53 puma.1    |   Cache digest for app/views/users/_user_sidebar.html.erb: bfc9447057c94bcfe13c18e391127f2d
13:31:53 puma.1    | Read fragment views/profiles/62-20160331112332689423000/bfc9447057c94bcfe13c18e391127f2d (0.2ms)
13:31:53 puma.1    |   Rendered users/_user_sidebar.html.erb (11.8ms)

回答1:

There is no way of getting around at least one database query since you need to know if the record has been updated since the digest was created.

You could load @profiles_sidebar sidebar upfront which would be somewhat better on a "cold" cache since its a single DB query:

@profiles_sidebar = Profile.order(created_at: :desc)
                           .limit(10)
                           .load

The actual difference between fetching a single record and 10 may be marginal though.

You also may want to use eager loading or includes to fetch both User and Profile in one query:

@profiles_sidebar = Profile.includes(:user)
                           .order(created_at: :desc)
                           .limit(10)
                           .load


回答2:

I suppose you are in development environment, are you sure do you have activated the cache in rails?? (by default it is disabled for dev env)

Make sure you have this line in your development.rb

config.action_controller.perform_caching = true