On Thursday, March 23, 2017 at 1:13:22 PM UTC-7, Andrew Burleson wrote:
>
> I've run into a weird case in my production app, which I haven't yet
> figured out how to reproduce locally, but I have been able to intercept and
> dig pretty deep on prod.
>
> Basically, there are situations where there are two different model
> instances representing the same row in the database, but comparing them
> with `==` returns false.
>
> Example:
>
> # Database Table: users
> # id | email | first_name | last_name
> # ---------------------------------------------
> # 1 | [email protected] | Joe | Example
>
> class User < Sequel::Model
> one_to_many :books
> end
>
> # Problematic code: during request we load current_user from session, and
> load a book based on a URL param.
> book.user_id #=> 1
> current_user.id #=>
> current_user.id == book.user.id #=> true
> current_user.to_hash == book.user.to_hash #=> true
> current_user == book.user #=> false
>
> This is causing me a bit of angst, as I can't figure out what would cause
> the two instances to not understand that they represent the same user.
>
> I can work around it by only comparing IDs, though there are other places
> where it causes problems because I have a set of users and calling
> `user_set.include?(user) ` will also fail when it should not, due to `==`
> returning false.
>
> I looked in the source code and I see that `==` aliases `eql?` which looks
> like this:
>
> def eql?(obj)
> (obj.class == model) && (obj.values == @values)
> end
>
> I'm pretty certain the issue must be there's *something* different inside
> the two object values, but given the hashes they output are the same I
> don't know what it is or how to tell.
>
It's hard to say what would cause this. Could you put together a
reproducible example?
>
> Jeremy, two questions for you (or anyone else who has hit this):
>
> 1) Are there any known "edge cases" where `==` will fail even though it
> seems like it shouldn't?
>
I'm not aware of any that are Sequel specific, but ruby has some, such as
the encoding of strings being different even though the content is the same.
> and
>
> 2) I see that `===` is implemented to check based on class and PK instead,
> which is more what I'd like. I'm nervous to locally override `==` to alias
> `===` instead of `eql?` as that seems like it would have bad ripple effects
> throughout the library.
>
I'm not sure. You could try making the change in Sequel, and running
Sequel's tests, and see what breaks.
> But is there any other way to get things like ruby's enumerable .include?
> method to work using === instead of == ?
>
# Change
enumerable.include?(foo)
# To:
enumerable.find{|x| x === foo}
Thanks,
Jeremy
--
You received this message because you are subscribed to the Google Groups
"sequel-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sequel-talk.
For more options, visit https://groups.google.com/d/optout.