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

Unify boolean quoting for Mysql- and Mysql2Adapter. #12425

Merged
merged 2 commits into from Nov 11, 2013

Conversation

Projects
None yet
7 participants
@senny
Member

senny commented Oct 2, 2013

This issue was raised with #11119. Fixed with #11120 and later reverted to prevent possible backward incompatible changes.

Since then I've written a bunch of test-cases to illustrate the behavior of Mysql2Adapters quoting and to reason about consequences of the patch.

@senny

This comment has been minimized.

Show comment
Hide comment
@senny
Member

senny commented Oct 2, 2013

@iwiznia

This comment has been minimized.

Show comment
Hide comment
@iwiznia

iwiznia Oct 23, 2013

Contributor

Why is this not merged already??? Please, merge it so it can be added to v4.0.1... it's a broken functionality!

Contributor

iwiznia commented Oct 23, 2013

Why is this not merged already??? Please, merge it so it can be added to v4.0.1... it's a broken functionality!

@senny

This comment has been minimized.

Show comment
Hide comment
@senny

senny Oct 23, 2013

Member

Even if we merge this one right now, it won't be part of 4.0.1. As this changes the functionality we probably won't even backport it to 4-0-stable and we'll have to wait for 4.1 until this gets released.

Member

senny commented Oct 23, 2013

Even if we merge this one right now, it won't be part of 4.0.1. As this changes the functionality we probably won't even backport it to 4-0-stable and we'll have to wait for 4.1 until this gets released.

@iwiznia

This comment has been minimized.

Show comment
Hide comment
@iwiznia

iwiznia Oct 23, 2013

Contributor

Bummer!
This bug (among other things) causes that if you define a uniqueness validator on a boolean column, it fails...

Contributor

iwiznia commented Oct 23, 2013

Bummer!
This bug (among other things) causes that if you define a uniqueness validator on a boolean column, it fails...

@senny

This comment has been minimized.

Show comment
Hide comment
@senny

senny Oct 23, 2013

Member

@iwiznia we are aware of that, that's where the issue originated from. (If you want to read back on the discussion, see the issues I linked at the top).

Member

senny commented Oct 23, 2013

@iwiznia we are aware of that, that's where the issue originated from. (If you want to read back on the discussion, see the issues I linked at the top).

@pixeltrix

This comment has been minimized.

Show comment
Hide comment
@pixeltrix

pixeltrix Oct 23, 2013

Member

@iwiznia I've never understood why people are putting validates_uniqueness_of on boolean columns - what's your use case?

Member

pixeltrix commented Oct 23, 2013

@iwiznia I've never understood why people are putting validates_uniqueness_of on boolean columns - what's your use case?

@iwiznia

This comment has been minimized.

Show comment
Hide comment
@iwiznia

iwiznia Oct 23, 2013

Contributor

Well it's only useful when using it with the scope option too.
A use case might look like: You have a user and a user has many payment methdos, but only one payment method can be active at any given time, so the payment method has an 'active' field which is boolean, and you want that value to be unique when it's set to true.

Contributor

iwiznia commented Oct 23, 2013

Well it's only useful when using it with the scope option too.
A use case might look like: You have a user and a user has many payment methdos, but only one payment method can be active at any given time, so the payment method has an 'active' field which is boolean, and you want that value to be unique when it's set to true.

@pixeltrix

This comment has been minimized.

Show comment
Hide comment
@pixeltrix

pixeltrix Oct 23, 2013

Member

You have a user and a user has many payment methdos, but only one payment method can be active at any given time, so the payment method has an 'active' field which is boolean, and you want that value to be unique when it's set to true.

Surely the better way to model this would be a active_payment_method_id column on the user model? Either way I'd see getting a validation error saying that I already had an active payment method as an annoyance - why not just change the active one to the one I'd just entered or selected if that's what I've indicated?

Member

pixeltrix commented Oct 23, 2013

You have a user and a user has many payment methdos, but only one payment method can be active at any given time, so the payment method has an 'active' field which is boolean, and you want that value to be unique when it's set to true.

Surely the better way to model this would be a active_payment_method_id column on the user model? Either way I'd see getting a validation error saying that I already had an active payment method as an annoyance - why not just change the active one to the one I'd just entered or selected if that's what I've indicated?

@iwiznia

This comment has been minimized.

Show comment
Hide comment
@iwiznia

iwiznia Oct 23, 2013

Contributor

Well, it depends on the use case, the case I described is a small example...
Besides, why would you add a new column to the user model if you can get the information anyway without it? I mean, you can have an association on the user that retrieves the active payment method without adding that column. Like so:

 has_one :active_payment_method, -> { where(active: true) }, class_name: 'PaymentMethod'
Contributor

iwiznia commented Oct 23, 2013

Well, it depends on the use case, the case I described is a small example...
Besides, why would you add a new column to the user model if you can get the information anyway without it? I mean, you can have an association on the user that retrieves the active payment method without adding that column. Like so:

 has_one :active_payment_method, -> { where(active: true) }, class_name: 'PaymentMethod'
@pixeltrix

This comment has been minimized.

Show comment
Hide comment
@pixeltrix

pixeltrix Oct 23, 2013

Member

The reason to use an attribute on the user model is one of atomicity - with the validation on the active attribute you have to first set the currently active payment method to false before you can set a new one to true. Also in the strictest send validates_uniqueness_of would only allow two payment methods - one with active: true and one with active: false, whereas what you really want is to ensure that only one payment method is active at any time.

Member

pixeltrix commented Oct 23, 2013

The reason to use an attribute on the user model is one of atomicity - with the validation on the active attribute you have to first set the currently active payment method to false before you can set a new one to true. Also in the strictest send validates_uniqueness_of would only allow two payment methods - one with active: true and one with active: false, whereas what you really want is to ensure that only one payment method is active at any time.

@iwiznia

This comment has been minimized.

Show comment
Hide comment
@iwiznia

iwiznia Oct 24, 2013

Contributor

Yes, you need to update the previous active to false first, but that's no problem... In the other solution, you also have 2 make 2 operations, first create the record, then associate it in the parent model, so it's basically the same.
And in my case I have an 'if' option to only run the validation when it's active.

Contributor

iwiznia commented Oct 24, 2013

Yes, you need to update the previous active to false first, but that's no problem... In the other solution, you also have 2 make 2 operations, first create the record, then associate it in the parent model, so it's basically the same.
And in my case I have an 'if' option to only run the validation when it's active.

@nanaya

This comment has been minimized.

Show comment
Hide comment
@nanaya

nanaya Oct 29, 2013

Contributor

@pixeltrix: by setting active: nil in a callback, it's possible to have one active: true and many active: nil. It is also a valid db unique index in some databases.

I'm also hitting this problem and I can't add another column because in my case, active (in my case, main) is scoped to another columns:

Tag:
- id

TagName:
- id
- name
- locale
- main
- tag_id

a tag can have many names, with each locale only have one main TagName.

validates :main, uniqueness: { scope: [:locale, :tag_id],
                               allow_nil: true }
Contributor

nanaya commented Oct 29, 2013

@pixeltrix: by setting active: nil in a callback, it's possible to have one active: true and many active: nil. It is also a valid db unique index in some databases.

I'm also hitting this problem and I can't add another column because in my case, active (in my case, main) is scoped to another columns:

Tag:
- id

TagName:
- id
- name
- locale
- main
- tag_id

a tag can have many names, with each locale only have one main TagName.

validates :main, uniqueness: { scope: [:locale, :tag_id],
                               allow_nil: true }

senny added a commit that referenced this pull request Nov 11, 2013

Merge pull request #12425 from senny/mysql_booleans
Unify boolean quoting for Mysql- and Mysql2Adapter.

@senny senny merged commit 0bb6b43 into rails:master Nov 11, 2013

@senny senny deleted the senny:mysql_booleans branch Nov 11, 2013

@arthurnn

This comment has been minimized.

Show comment
Hide comment
@arthurnn

arthurnn Mar 3, 2014

Member

Can we backport this to 4-0-stable? @carlosantoniodasilva @senny

Member

arthurnn commented Mar 3, 2014

Can we backport this to 4-0-stable? @carlosantoniodasilva @senny

@senny

This comment has been minimized.

Show comment
Hide comment
@senny

senny Mar 3, 2014

Member

@arthurnn better not. This actually changes behavior. I hope no-one is actively relying on the old one but better save than sorry.

Member

senny commented Mar 3, 2014

@arthurnn better not. This actually changes behavior. I hope no-one is actively relying on the old one but better save than sorry.

@akaspick

This comment has been minimized.

Show comment
Hide comment
@akaspick

akaspick Mar 19, 2014

Contributor

I'm finally getting around to upgrading a rails 3.2 app to rails 4 and use the uniqueness validation on a boolean field with a scope and this issue breaks it as already mentioned. What I don't see is a suggested fix for this regression. What are people currently doing to get this working again with rails 4?

Contributor

akaspick commented Mar 19, 2014

I'm finally getting around to upgrading a rails 3.2 app to rails 4 and use the uniqueness validation on a boolean field with a scope and this issue breaks it as already mentioned. What I don't see is a suggested fix for this regression. What are people currently doing to get this working again with rails 4?

@byroot

This comment has been minimized.

Show comment
Hide comment
@byroot
Member

byroot commented Mar 19, 2014

@akaspick

This comment has been minimized.

Show comment
Hide comment
@akaspick

akaspick Mar 19, 2014

Contributor

@byroot Thanks. Works perfectly.

Contributor

akaspick commented Mar 19, 2014

@byroot Thanks. Works perfectly.

@lukaszx0 lukaszx0 referenced this pull request Jul 11, 2014

Merged

Mysql bool fix #51

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment