-
-
Notifications
You must be signed in to change notification settings - Fork 911
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
Issue with Shoulda::Matchers::ActiveRecord::Uniqueness::TestModels #854
Comments
For the record I temporarily fixed the issue by adding this code in spec setup. allow_any_instance_of(AASM::Persistence::ActiveRecordPersistence::InstanceMethods).
to receive(:aasm_ensure_initial_state).and_return(true) |
Can you post the exception that was raised along with the backtrace? |
Of course, here it is
Is caused by this line triggered in an after_initialize callback because it uses object class as key. And here's a minimal AR class to reproduce this error class Bookmark < ActiveRecord::Base
belongs_to :user, required: true, touch: true
belongs_to :bookmarkable, polymorphic: true, required: true
# Prevent users to add same bookmark twice
validates_uniqueness_of :user_id, scope: [:bookmarkable_id, :bookmarkable_type]
end However notice that AASM is not used in |
Okay, thanks for that. What the uniqueness matcher is doing is this:
So in your case, it would follow these steps:
Notice how the matcher has to choose a new value for So the way that we handle this situation is to make a new ActiveRecord model at runtime which is namespaced under That's the rationale behind what you're seeing. As for the cause of this issue, I'm not really sure -- it seems odd to me that your Bookmark model, as well as AASM, even cares what We may be able to fix this by having our generated model inherit from Place. But I'd have to dig into this to know exactly what's going on here. I think you may have to test this one yourself. I can give you some guidance on this if you like. |
By looking at your explanation and at the code I think there's nothing more that you can do in matcher code. The class has to be different to correctly specs uniqueness constraint. Maybe it's an issue in aasm itself (I have to try if it works with STI, I don't use it), however I think that shoulda-matchers code is fine as is, thus this issue can be closed if you agree. For my specific issue, I can solve it using the stub above or by changing the bookmarkable item using a class that doesn't use aasm. |
Alright, sounds good. If you play around with it some more and figure out a fix then let me know and I can revisit this. |
For the record I found out that aasm works with STI so maybe a little improvement you can do in your code is to create the test model as subclass of original class, but as I said before it's an edge case that you can probably ignore. |
The uniqueness validation matcher generates a fake class when the scope name ends on _type. This fake class is a duplicate of the original class. In most cases this is not a problem, however when using single table inheritance (STI), this new fake class is not a subclass of the original class and therefore ActiveRecord will throw an error. See thoughtbot#1245 A similar thing happens when the original class is using an AASM state machine. The state machine settings are stored in a global registry. So when the fake class is initialized, AASM cannot find the settings of the set state machines (due to duplication) in the registry. See thoughtbot#854 These problems are fixed by making the fake class inherrit from the original class. Therefore it closes thoughtbot#1245 and closes thoughtbot#854
The uniqueness validation matcher generates a fake class when the scope name ends on _type. This fake class is a duplicate of the original class. In most cases this is not a problem, however when using single table inheritance (STI), this new fake class is not a subclass of the original class and therefore ActiveRecord will throw an error. See thoughtbot#1245 A similar thing happens when the original class is using an AASM state machine. The state machine settings are stored in a global registry. So when the fake class is initialized, AASM cannot find the settings of the set state machines (due to duplication) in the registry. See thoughtbot#854 These problems are fixed by making the fake class inherrit from the original class. Therefore it closes thoughtbot#1245 and closes thoughtbot#854
The uniqueness validation matcher generates a fake class when the scope name ends on _type. This fake class is a duplicate of the original class. In most cases this is not a problem, however when using single table inheritance (STI), this new fake class is not a subclass of the original class and therefore ActiveRecord will throw an error. See thoughtbot#1245 A similar thing happens when the original class is using an AASM state machine. The state machine settings are stored in a global registry. So when the fake class is initialized, AASM cannot find the settings of the set state machines (due to duplication) in the registry. See thoughtbot#854 These problems are fixed by making the fake class inherrit from the original class. Therefore it closes thoughtbot#1245 and closes thoughtbot#854
The uniqueness validation matcher generates a fake class when the scope name ends on _type. This fake class is a duplicate of the original class. In most cases this is not a problem, however when using single table inheritance (STI), this new fake class is not a subclass of the original class and therefore ActiveRecord will throw an error. See #1245 These problems are fixed by making the fake class inherrit from the original class. Therefore it closes #1245 and closes #854
The uniqueness validation matcher generates a fake class when the scope name ends on _type. This fake class is a duplicate of the original class. In most cases this is not a problem, however when using single table inheritance (STI), this new fake class is not a subclass of the original class and therefore ActiveRecord will throw an error. See #1245 These problems are fixed by making the fake class inherrit from the original class. Therefore it closes #1245 and closes #854 Co-authored-by: Stef Schenkelaars <stef.schenkelaars@gmail.com>
I've just upgraded aasm gem to latest version and now I have a failing shoulda matcher (version 2.8.0) spec. The code is pretty standard, I have a
Bookmark
model which belongs to a user and a bookmarkable (polymorphic) item. A given user can only bookmark items once thus I have this spec:Running this spec with latest aasm code raises an error. I tracked the error to this line in aasm code. The issue is that the bookmarkable item (passed in matcher by shoulda code) does not retain its original class.
In my spec setup I create a Bookmark using a factory and matcher code uses that factory to compute values for assertion. My factory returns an instance of
Place
for bookmarkable while in some way the class of bookmarkable used in matcher isThat name is likely generated by this code, however I don't know its purpose.
In any case I think that test models generated by your matcher should behave like original one, so they should return original class when
#class
is called on their instance.The text was updated successfully, but these errors were encountered: