Question

I have a method:

def fb_matches_for_friend_employer_goals(user, friend)
    User.where( :is_reachable_on_fb   => true,                          # Users that are reachable on FB via wall posts
                "jobs.employer"       => friend.interested_employers,   # Users that have worked at the employers the friend is interested
                :fb_user_id           => user.fb_connections,           # Users that are friends of user through FB
                :fb_user_id.nin       => friend.fb_connections,         # Users that are NOT friends with the friend through FB
                :fb_user_id.ne        => user.fb_user_id,               # Users that are NOT the user
                :fb_user_id.ne        => friend.fb_user_id              # Users that are NOT the friend (although it's likely the friend hasn't worked at the goal employer)
    ).fields(:id, :jobs, :fb_connections).all
  end 

And a test:

  describe "#fb_matches_for_friend_employer_goals method" do
    let(:friend) { stub_model(User) }

    before(:each) do
      User.stub(where: User, fields: User, all: User)
      friend.stub(interested_employers: ["Apple"])
      friend.stub(fb_connections: ["100", "200"])
      friend.stub(fb_user_id: "1")        
      user.stub(fb_connections: ["101", "201"])
      user.stub(fb_user_id: "2")
    end

    it "returns users that are reachable on FB" do
      User.should_receive(:where).with( :is_reachable_on_fb   => true,
                                        "jobs.employer"       => ["Apple"],
                                        :fb_user_id           => ["101", "201"],
                                        :fb_user_id.nin       => ["100", "200"],
                                        :fb_user_id.ne        => "2",
                                        :fb_user_id.ne        => "1")
      a.fb_matches_for_friend_employer_goals(user, friend)
    end

  end

I get the following error:

Failures:

    1) Algorithm::Helpers::Facebook#fb_matches_for_friend_employer_goals method returns users           that are reachable on FB
 Failure/Error: User.should_receive(:where).with( :is_reachable_on_fb   => true,
   <User (class)> received :where with unexpected arguments
     expected: ({:is_reachable_on_fb=>true, "jobs.employer"=>["Apple"], :fb_user_id=>["101", "201"], #<SymbolOperator:0x007f9e28bac958 @field=:fb_user_id, @operator="nin">=>["100", "200"], #<SymbolOperator:0x007f9e28bac778 @field=:fb_user_id, @operator="ne">=>"2", #<SymbolOperator:0x007f9e28bac688 @field=:fb_user_id, @operator="ne">=>"1"})
          got: ({:is_reachable_on_fb=>true, "jobs.employer"=>["Apple"], :fb_user_id=>["101", "201"], #<SymbolOperator:0x007f9e28babcd8 @field=:fb_user_id, @operator="nin">=>["100", "200"], #<SymbolOperator:0x007f9e28bab6c0 @field=:fb_user_id, @operator="ne">=>"2", #<SymbolOperator:0x007f9e28bab148 @field=:fb_user_id, @operator="ne">=>"1"})
 # ./spec/lib/algorithm/helpers/facebook_spec.rb:44:in `block (3 levels) in <module:Helpers>'

From what I can tell, it's just that the SymbolOperators are different. any thoughts on how to avoid this and confirm the right hash is going into the query?

Was it helpful?

Solution

The problem has to do with the way hash equality is calculated in Ruby.

1.9.2-p0 :001 > :something.nin == :something.nin
 => true
1.9.2-p0 :002 > {:something.nin => 'hi'} == {:something.nin => 'hi'}
 => false
1.9.2-p0 :003 > {:something => 'hi'} == {:something => 'hi'}
 => true

For efficiency, I guess Ruby is comparing the hash-codes rather than doing actual == comparisons.

1.9.2-p0 :004 > {:something => 'hi'}.hash
 => 2493047093815769983 
1.9.2-p0 :005 > {:something => 'hi'}.hash
 => 2493047093815769983
1.9.2-p0 :006 > {:something.nin => 'hi'}.hash
 => 2609636779135588412
1.9.2-p0 :007 > {:something.nin => 'hi'}.hash
 => -424522258459261487
1.9.2-p0 :008 > :something.hash
 => 3062293424662012631
1.9.2-p0 :009 > :something.hash
 => 3062293424662012631
1.9.2-p0 :010 > :something.nin.hash
 => -1304763062464413657 
1.9.2-p0 :011 > :something.nin.hash
 => 2727789822935992035

The most permanent fix for your trouble is to define hash for symbol operators and submit a pull request to plucky. There's some discussion here on writing a hash implementation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top