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.

Reply via email to