-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Default store headaches on 1.3 #1225
Comments
Agreed
For some reason that feels a bit scary to me.
I like that idea. I think it'll prevent more errors than it'll cause. Or perhaps we could instead (or in addition) remove the |
The current Store.default implementation is screwy, creating a non-persisted store with So if you call So while I agree lazily creating a store in So my initial thought was to just change But this doesn't work, because a Store can't be saved without a So maybe The problem is this will make a whole bunch of tests in my local app fail, that have always passed before. I'm probably not alone. Because I use DatabaseCleaner to wipe the database in between every test (I guess solidus suite does not do this?), so there's always 0 Spree::Store's at the beginning of a test. But after this change, any test that involves I have run into related problems like this with test environments and 'seed' data, and I have no good general purpose solution, I've always ended up having to write code I didn't like. Incidentally, in investigating it, I discovered that the [current specs for Spree::Store.default](current_order%28create_order_if_neccesary: true%29) are pretty useless. They say they are testing to make sure |
The Some other places where we have "default" methods:
All of those return nil if there is no default set. The only one I could find that behaves similar to this was |
@jrochkind I believe the
I feel like intuitively that's what I'd expect. If we could get there w/o breaking things for people too much I think it'd be great. |
FYI another issue I've had while upgrading is that |
Would that require a lot of change? A new issue that came up for me in rc1 was from this change on |
Aha, right. However, I think in fact, if anything does try to save the thing lazily created from |
Great points. |
Does anyone know how Solidus' own specs take care of making sure a default store is there? I know a default store starts out in the generated dummy app, which I guess works if you're using transactional test destroy method, but that doesn't work for capybara feature tests, they presumably wipe out the whole db... frontend at least is using I guess I can try to debug it and figure it out. |
That's originally why I introduced the validation in the first place. If I don't have it, code down the line has to provide paths for the Additional food for thought: I think the vast majority of users has only one store, and those that don't will have a |
In my view
So, I think a default store should be automatically created and class memorized. I just recently did that for a single-store site to avoid all those db lookups on every request. def current(domain = nil)
@@current_store ||= Spree::Store.default
end That has the disadvantage that an app restart will be required if someone changes the default store, but I think the benefits are worth the minor inconvenience. |
@mtomov I agree with your bullet points as desirable, but I've found it awfully hard to implement. It's pretty dangerous to keep an AR in a class attribute, as it'll end up shared between threads in many scenarios (including worker threads, multi-threaded dispatch with puma, and others), and AR models are not thread-safe to be shared between threads. If you marked it I think sharing an AR model between threads, as will happen eventually if it's cached at the class level, is probably a not good idea. So I'm not sure there's any good way to accomplish those points, if every order needs a store, which has already been committed to I think? It is a pickle. |
Something that seems to be popping up early on in the Solidus 1.3.0.rc1 upgrades is issues with the new requirement that all orders have an attached
store
.This was introduced in #935, which IMO is a great change, it will simplify a lot being able to rely on the store being set. However we should do whatever possible to make the upgrade smooth.
Previously,
Store.default
would returnStore.new
if there was no existing default (to simplify writing specs, presumably). This is no longer a valid "default" in most cases, since anid
will be required to make the store valid. This will make operations likecurrent_order(create_order_if_neccesary: true)
break if no store is in the database.Things we must do
Some options we could consider:
Store.default
could create a default store if none exists. This would makecurrent_order(create_order_if_neccesary: true)
work in specs (largely) as it used to.Store.default
raise an error if there is no default Store. This won't make anything pass which was broken by this, but would give better indication of the issue.Order#store_or_default
to help any pieces of code which want to reliably get a store.The text was updated successfully, but these errors were encountered: