-
-
Notifications
You must be signed in to change notification settings - Fork 909
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 validates uniqueness and STI/polymorphic models on rails 6? #1245
Comments
This is happening to me as well |
it's likely due to : # shoulda-matchers-4.1.2/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb
def next_scalar_value_for(scope, previous_value)
column = column_for(scope)
# scope == :polymorphic_type,
# `previous_value` is an instance of the model we are testing,
# some dumb values and a real existing `polymorphic_type` such as `MySTIType`
# previous_value == MyModel(title: "dummy", polymorphic_type: MySTIType, ...)
# which the #create method will replace with the incirminated value :
# Shoulda::Matchers::ActiveRecord::Uniqueness::Namespace::MySTITypf]
if column.type == :uuid
# ...
elsif polymorphic_type_attribute?(scope, previous_value)
Uniqueness::TestModels.create(previous_value).to_s
# ...
end
end It triggers a I don't know why. I just tracked it down to this. I have the exact same problem, my Edit Apparently, it is meant to be this way |
Yes, that behavior is intentional. The uniqueness matcher will:
It's this last step that's tricky. What do I mean by "changing" a value? I mean that the matcher will look at the existing value for the attribute, whatever it happens to be, and create another value based on it which is different. How this works differs based on the type of the value. For "simple" data types like strings, numbers, etc., this is easy: call Shoulda::Matchers::ActiveRecord::Uniqueness::TestModels::Producu = Product @mjankowski @diebas Is there something specific about your models that would cause the error that you're seeing? Something you've done differently? |
My issue was happening in a rails six upgrade of branch of Upcase, which is a public repo, so I can actually link you to the "fix" I came up with. Prior to this commit - thoughtbot/upcase@9f0792b - I was seeing the In this specific case, I'm not actually sure why the validation and spec were written the way they were to begin with ... so the change both made logical common sense to me as a better way to state the same thing, but it also fixed the shoulda matcher generated error. |
I think it's a rails "issue". Maybe in rails (ActiveRecord) 5, models weren't checking, or not the same way, what was put in the Or maybe we can make the matcher inherits from the STI parent ? |
not sure what side effect it has, but removing the def symlink_to(parent)
namespace.set(name, parent.dup)
end fix the issue (as the |
@ngouy Hmm.... I wonder why I ended up doing that. Thanks for the tip. I'll try this out and see if it breaks anything. |
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
Hey, thanks for your efforts! |
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>
This feels similar to this long-ago bug - #203 - which was fixed here - #592
Model of:
Spec of:
Relevant output is:
That
::Producu
on the very end there in the error makes me suspect that we're callingnext
on a string withProduct
(or something?) somewhere in the codebase.The text was updated successfully, but these errors were encountered: