-
Notifications
You must be signed in to change notification settings - Fork 21.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove special handling for ActiveRecordStore #45395
Conversation
Your application has a session for each user in which you can store small amounts of data that will be persisted between requests. The session is only available in the controller and the view and can use one of several of different storage mechanisms: | ||
Your application has a session for each user in which you can store small | ||
amounts of data that will be persisted between requests. The session is only | ||
available in the controller and the view. The storage mechanism can be | ||
configured to a store provided by an external gem or one that Rails provides by | ||
default: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of changing this part, what if we added a mention of third-party gems as a bullet point to the list below? Maybe something like:
* A custom store or a store provided by a third-party gem.
|
||
* [`ActionDispatch::Session::CookieStore`][] - Stores everything on the client. | ||
* [`ActionDispatch::Session::CacheStore`][] - Stores the data in the Rails cache. | ||
* `ActionDispatch::Session::ActiveRecordStore` - Stores the data in a database using Active Record (requires the `activerecord-session_store` gem). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The activerecord-session_store
gem is still being maintained under the rails
org, so let's keep this. We can link to https://github.com/rails/activerecord-session_store though, and lean on its README for documentation purposes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I tried to find some context on the reasoning for extraction to a gem but came up short. I was curious what prompted it and whether that meant it should be recommended/documented.
Adding it back for now but I do think getting the context would be a big plus
# Use the database for sessions instead of the cookie-based default, | ||
# which shouldn't be used to store highly confidential information | ||
# (create the session table with "rails g active_record:session_migration") | ||
# Rails.application.config.session_store :active_record_store | ||
# Rails.application.config.session_store :cache_store |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good change! 👍 We might also consider linking to the configuration guide below this example. Something like:
See the [configuration guide](configuring.html#config-session-store) for more information.
@session_store = new_session_store | ||
@session_options = options || {} | ||
else | ||
case @session_store | ||
when :disabled | ||
nil | ||
when :active_record_store | ||
ActionDispatch::Session::ActiveRecordStore | ||
when Symbol | ||
ActionDispatch::Session.const_get(@session_store.to_s.camelize) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea here is to just rely on the logic in the when Symbol
branch to resolve :active_record_store
, yes? Sounds good! 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I left the test to ensure it keeps working too: https://github.com/rails/rails/blob/b88de15888b2ced7cac03508e1c28845e3d30034/railties/test/application/configuration_test.rb#L1641
if new_session_store == :active_record_store | ||
begin | ||
ActionDispatch::Session::ActiveRecordStore | ||
rescue NameError | ||
raise "`ActiveRecord::SessionStore` is extracted out of Rails into a gem. " \ | ||
"Please add `activerecord-session_store` to your Gemfile to use it." | ||
end | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm on the fence about removing this. Without it, the error would be just "uninitialized constant ActionDispatch::Session::ActiveRecordStore (NameError)", which is not nearly as helpful.
What about adding a helpful, general error message by rescuing NameError
raised by the ActionDispatch::Session.const_get
further below. Roughly something like:
Could not resolve session store #{@session_store.inspect}.
#{@session_store.inspect} resolves to ActionDispatch::Session::#{@session_store.to_s.camelize}, but ActionDispatch::Session::#{@session_store.to_s.camelize} is not defined.
Is #{@session_store.inspect} spelled correctly, and are the necessary gems installed?
It might be possible to add some kind of did-you-mean suggestions based on the constants under ActionDispatch::Session
, but that may be more trouble than it's worth. (And could be a separate PR.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea for a DYM error, I'll take a stab at that in a follow up PR
b88de15
to
ec7ec44
Compare
My most recent commit's test failure is real:
It looks like trying to load Edit: |
https://gist.github.com/skipkayhil/1897d8bfcea72003c58a9ebcdf17f3c7 |
2843fd0
to
a00c37d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to push an update that doesn't try to constantize the store until it gets used (in
default_middleware_stack
) but I'm not sure its the best solution.
That was what I originally had in mind — I hadn't really thought about doing an eager check. I think it would be possible by using ActionDispatch::Session.const_defined?
, which shouldn't autoload. But I'm not sure if it's worth the extra code. What you have now isn't much worse for :active_record_store
, and is definitely better for e.g. :activerecord_store
or :memcache_store
.
Also, I have not looked, but do we have adequate test coverage for when config.session_store
(and thus ActionDispatch::Session.resolve_store
) fails to resolve a store?
actionpack/lib/action_dispatch.rb
Outdated
def self.resolve_store(session_store) | ||
self.const_get(session_store.to_s.camelize) | ||
rescue NameError | ||
raise <<~ERROR | ||
Unable to resolve session store :#{session_store}. | ||
|
||
:#{session_store} resolves to ActionDispatch::Session::#{session_store.to_s.camelize}, | ||
but that class is undefined. | ||
|
||
Is :#{session_store} spelled correctly, and are the necessary gems installed? | ||
ERROR | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this extraction! 😍
I wanted to point out a subtle difference between ":#{session_store}"
and "#{session_store.inspect}"
. Symbols can include arbitrary characters, including slashes which are validly "camelized" to "::"
:
symbol = :"my_namespace/my_store"
puts symbol.to_s.camelize
# => MyNamespace::MyStore
puts ":#{symbol} versus #{symbol.inspect}"
# => :my_namespace/my_store versus :"my_namespace/my_store"
So it might be better to use session_store.inspect
here.
a00c37d
to
782a263
Compare
activerecord-session_store was removed in 0ffe190, and has been displaying a special error message when missing since Rails 4.0. Replace the specific error message so that third party stores get nicer error handling as well
782a263
to
27285e7
Compare
Thank you, @skipkayhil! 👍 |
Summary
activerecord-session_store was removed in 0ffe190, and has been
displaying a special error message when missing since Rails 4.0.
Replace the specific error message so that third party stores get nicer
error handling as well