Rails.cache.fetch caching in development - ruby-on-rails

Using Rails.cache.fetch like below is caching even in my development environment (with caching turned off):
#boat_features = Rails.cache.fetch("boat_features", expires_in: 10.minutes) do
BoatFeature.all
end
Has anyone run into this before?

That's normal. That sort of caching isn't turned off in development. In a previous app where this was a problem we used the memory store and then added a middleware that did Rails.cache.clear after every request.
Something like
config.middleware.use ClearCache
in development.rb
and then your ClearCache middleware should look something like
class ClearCache
def initialize(app)
#app = app
end
def call(env)
#app.call(env)
ensure
Rails.cache.clear
end
end
In Rails 3.2 there's also ActiveSupport::Cache::NullStore

I had the same problem. I worked around a lot then came up with this simple solution. In your development configuration file config/environments/development.rb add these settings
config.perform_caching = false
config.cache_store = :null_store

Related

Overriding const_missing returns `NameError uninitialized constant` in non-dev environments

I have the following code in my rails app
# app/models/test_module/text_class.rb
module TestModule
class TestClass
end
end
# app/models/test_module.rb
module TestModule
def self.const_missing(name)
super(delete_end_number(name.to_s).to_sym)
end
def self.delete_end_number(str)
str.gsub(/\d+$/,'')
end
end
When it runs in development it works
>> TestModule::TestClass1
=> TestModule::TestClass
When I run it in production however I get
NameError (uninitialized constant TestModule::TestClass)
If I just copy TestModule::TestClass into the console it works. It seems just to not work with the const_missing method.
I suspect it may have something to do with the autoloading as when I set config.cache_classes and config.eager_load to true in development.rb it happens there too. I can't seem to figure out how to get it to work in cached environments though.
Change from
super(delete_end_number(name.to_s).to_sym)
To
const = delete_end_number(name.to_s).to_sym
ActiveSupport::Dependencies.load_missing_constant(self, const)

Correct way to load middleware for rails and rspec

So... I have a bit of a conundrum.
I've written some rack middleware, it's stored on disk at app/middleware/eat_bacon.rb, it looks something like
module Middleware
class EatBacon
def initialize(app)
#app = app
end
def call(env)
Thread.current[:mouth] = 'Bacon'
#app.call(env)
end
end
end
I'm trying to load / use some middleware in a rails-api (rails 3.2.19)
In my config/application.rb I've gotten the middleware to load in two different ways, one way works when running the app, the other way works for rspec
Works for running app
config.middleware.insert_before 0, 'Middleware::EatBacon'
but when I run rspec, I get
/Volumes/HardDrive/Me/.rvm/gems/ruby-2.0.0-p451#bacon/gems/activesupport-3.2.19/lib/active_support/inflector/methods.rb:230:in `block in constantize': uninitialized constant Middleware (NameError)
Works for RSpec
config.after_initialize do
config.middleware.insert_before 0, 'Middleware::EatBacon'
end
But now the middleware is not loaded when the application runs, ie Thread.current[:mouth] never gets bacon
Seems weird to have to implement this differently in config/environments/test.rb and config/environments/production.rb, but I guess thats what I'll end up doing unless someone has a better idea
The way I solved this was to first move the middleware to the lib folder:
lib/middleware/eats_bacon.rb
AND Then, in config/application.rb I added a require_relative, so that file now looks like
...
Bundler.require(*Rails.groups)
require_relative '../lib/middleware/eats_bacon.rb'
module BaconEaterApp
class Application < Rails::Application
...
Then at the bottom of that file
...
# Middleware
config.middleware.insert_before 0, 'Middleware::EatBacon'
...

Rails 2.3.2 and SHOW TABLES

I have annoying problem with SHOW TABLES in my Rails 2.3.2 APP - it is slowing my APP very deep. The question is, how to get rid of SHOW TABLES usage and where it is used in Rails framework? From APP logs I can see that it is being used all the time.
Thank you!
config/environments/production.rb:
config.cache_classes = true
config.action_controller.consider_all_requests_local = false
config.action_controller.perform_caching = true
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
"SHOW TABLES" is ORM-dependent SQL query, it fires with every action to provide classes reload in development mode. How much time does the query take?
I was seeing a similar problem in Rails 3.0 and was able to fix it using the gist pointed to from this issue. Looks like it's fixed in Rails 3.2.
I added ar_patch.rb to config/initializers with this code:
unless Rails.env.development?
require "active_record/connection_adapters/mysql2_adapter"
module ActiveRecord
module ConnectionAdapters
class Mysql2Adapter < AbstractAdapter
extend ActiveSupport::Memoizable
memoize :tables, :pk_and_sequence_for, :columns
end
end
end
end

analytics if on production site, not a local or heroku subdomain

This question is about getting an analytics script to run in one of these three environments.
mysite.heroku.com
mysite-staging.heroku.com
mysite.com - this is the only one I want it to run on.
This is how I plan to lay it out, but any suggestions are welcome.
In my helper
def render_analytics
if local_request? || #on a Heroku subdomain
false
else
true
end
end
In my layout
<%= render 'shared/analytics' if render_analytics %>
render_analytics returns a boolean: true if on mysite.com, false if a local_request? or on a Heroku subdomain (ex: mysite.heroku.com || mysite-staging.heroku.com)
So how can I find out if it is coming from Heroku.
Use hostname:
if local_request? || `hostname` =~ /heroku/i
A cleaner solution is to set a constant in your environment during deployment that allows you to know whether you are on Heroku. As the Heroku deploy process is pretty opaque in terms of letting you dork around with config files, you might have your method memoize the result so you aren't doing a system call each time you render a view.
I just did something similar with a method that checks the database adapter to account for differences between my development environment and Heroku. Here's my lib/adapter.rb:
class Adapter
cattr_reader :adapter
def self.postgres?
##adapter ||= Rails.configuration.database_configuration[Rails.env]['adapter']
adapter == 'postgresql'
end
def self.mysql?
##adapter ||= Rails.configuration.database_configuration[Rails.env]['adapter']
adapter == 'mysql'
end
def self.sqlite?
##adapter ||= Rails.configuration.database_configuration[Rails.env]['adapter']
adapter.include?('sqlite')
end
end
Note that in addition to this, you have to change application.rb such that lib is added to your autoload path:
config.autoload_paths += Dir["#{config.root}/lib/**/"] # include all subdirectories

Why the Rails.cache.read can't get anything in ApplicationController?

I have a problem with my Ruby on rails application. The Ruby on Rails Cache in ApplicationController.
The data can't get, but it exists.
class ApplicationController < ActionController::Base
before_filter :init
def init
#setting = Rails.cache.read("data/setting")
if not #setting
#setting = Setting.find_create
Rails.cache.write("data/setting",#setting)
end
end
end
Development.log show this:
Cache read: data/setting
Setting Load (0.5ms) SELECT * FROM > "settings" LIMIT 1
Cache write: data/setting
Why is this happening?
If you are running your app in development mode, it's likely that caching is turned off. Check your config/development.rb file for the following:
config.action_controller.perform_caching = false
To test your caching you can either change this value to true, or run in a different environment where caching is turned on. I often create an environment development_as_production, pointing at the development db, but with my production.rb settings.
I am Json, I was changed the name.
But the development environment setting current is:
config.action_controller.perform_caching = true
The perform_caching was trun on!
The others caches can working. only this cache didn't working (It's in the ApplicationController).
#setting = Rails.cache.read("data/setting")
if not #setting
#setting = Setting.find_create
Rails.cache.write("data/setting",#setting)
end
Why? Is Rails.cache.read can't working in the ApplicationController?

Resources