Comments (5)
For the reasons @rsmithlal mentioned, using scope
is probably a bad idea. Thankfully validates_uniqueness_of
comes with a conditions option. Using that I think you can achieve what you want with something like:
validates_uniqueness_of :email, conditions: -> { where(discarded_at: nil) }
# or:
validates :email, uniquess: { conditions: -> { where(discarded_at: nil) } }
This should only check uniqueness of emails on non 'deleted' (AKA discarded) records.
from discard.
@JamesDullaghan You can add an index to support the validation if you are using a nice database (PostgreSQL, MySQL...).
It would prevent undiscarding records though if there has been a conflicting record created, as @rsmithlal mentioned.
To insulate yourself from the potential craziness, you may want to have two unique indexes, ensuring you only ever have one discarded and one not discarded. It will depend on how you intend to use the data.
class AddUniquenessConstraint < ActiveRecord::Migration[5.2]
def change
add_index :users, %i[email], where: '(discarded_at IS NOT NULL)', name: 'idx_users_email_discarded_at_not_null'
add_index :users, %i[email], where: '(discarded_at IS NULL)', name: 'idx_users_email_discarded_at_null'
end
end
from discard.
It's possible that you would have to rework your uniqueness validator to capture information about the discarded_at
column. I know that when defining one, you can pass a scope
option, so that might be helpful.
One issue to be aware of with conditionally validating the uniqueness of your column for discarded and undiscarded records is that you might not be able to undiscard records if the column value is later used by another undiscarded record. For example, let's say that I have a discardable User
class with a uniqueness validator on its email
attribute. I scope the validator to some attribute that divides the set between discarded and undiscarded records. I create a user with the email [email protected]
. I decide to discard that user record, and later someone else creates a user with the email [email protected]
. I now have two User
records in the system with the email [email protected]
, one discarded and one undiscarded. Because that attribute must be unique, I can no longer undiscard the original [email protected]
user record.
Another issue with this approach might be that the value for the discarded_at
column will almost always be a unique datetime, so you might have to add a boolean discarded
column to your tables to use as your validator scope and set it using a before_discard
callback. That way, your validator will check for a unique combination of each the column being validated and whether or not it has been discarded. This might not be ideal, but I suspect that it would work. If you do take this approach, be sure to define an callback for before_undiscard
that reverses the value.
from discard.
I think Rails uniqueness validations should be skipped now, and as outlines above, the trick is to use a composite index that includes the discarded_at
timestamp.
from discard.
@JamesDullaghan You can add an index to support the validation if you are using a nice database (PostgreSQL, MySQL...).
It would prevent undiscarding records though if there has been a conflicting record created, as @rsmithlal mentioned.
To insulate yourself from the potential craziness, you may want to have two unique indexes, ensuring you only ever have one discarded and one not discarded. It will depend on how you intend to use the data.
class AddUniquenessConstraint < ActiveRecord::Migration[5.2] def change add_index :users, %i[email], where: '(discarded_at IS NOT NULL)', name: 'idx_users_email_discarded_at_not_null' add_index :users, %i[email], where: '(discarded_at IS NULL)', name: 'idx_users_email_discarded_at_null' end end
shouldn't there be a unique: true
on the second index?
EDIT: oops didnt see the "It will depend on how you intend to use the data"
from discard.
Related Issues (20)
- Bang-Methods hides internal errors (e.g. ActiveModel::ValidationError) HOT 1
- Discarded scope doesnt work properly HOT 1
- discard has_and_belongs_to_many association HOT 1
- Discard callbacks don't work with observers HOT 3
- NoMethodError (undefined method `undiscarded?' ... HOT 4
- is discard_all! working on version 1.1.0 HOT 2
- after_discard_commit HOT 1
- All new records are discarded use-case HOT 2
- Run callbacks inside of the same transaction HOT 5
- Rails 7 is here, why not drop the upper version dependency? HOT 1
- Support for Rails 7.0.0 HOT 2
- Add the ability to use `dependent: :discard` in associations HOT 1
- Nil when finding has_one association HOT 2
- how is the integration with papertrail? HOT 1
- dependent: :discard HOT 12
- Sequel Support HOT 1
- guard on discard HOT 1
- `self.class.discard_column` as a boolean `is_discarded` for "if" and use `updated_at` for "when" HOT 1
- `def undiscard` doesn't follow `return false` pattern HOT 1
- .discarded query HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from discard.