Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

find_or_create_by multiple attributes not finding records when called in context of belongs_to object (AR bug in 2.3.11?)

I am adding omniauth to a rails 2.3.11 application with devise. I'm basically following Ryan Bate's railscast (with appropriate modifications for rails 2.3). But I'm seeing something very odd in testing this part of the code:

class AuthenticationsController < ApplicationController
  ...

  def create
    auth = request.env["omniauth.auth"]
    current_user.authentications.find_or_create_by_provider_and_uid(auth['provider'], auth['uid'])
    flash[:notice] = "Authentication successful."
    redirect_to authentications_url
  end

  ...
end

The find_or_create always creates. In the log, I see this select:

SELECT * FROM `authentications` WHERE (`authentications`.`provider` IN ('facebook','XXXXXXX') AND `authentications`.`uid` IS NULL) AND ((`authentications`.`user_id` = 10)) LIMIT 1

That is not the right select for that method. auth['provider'] and auth['uid'] are populated correctly (and it creates the new record just fine).

More perplexing: If I go into the console and do Authentication.find_or_create_by_provider_and_uid('facebook', 'XXXXX'), it works fine (it finds the existing record). But if I get a user and do user.authentications.find_or_create_by_provider_and_uid('facebook', 'XXXXX'), it creates a new record and I see the same problematic query statement in the log.

I know I can work around this (and Ryan Bates changes this code later anyway), but this is very troubling. Am I missing something or does this look like a bug in ActiveRecord?

This is not specific to OmniAuth or Devise. Before submitting this, I tried it with two other classes (rather simple classes). Same result [ Klass.find_or_create_by_a_and_b('A','B') works but parent.klasses.find_or_create_by_a_and_b('A','B') generates a select that wants b to be null and a in ('A','B')].

Now I'm definitely thinking this is a bug 2.3.11. Before I submit a bug, does anybody see anything I'm missing? Has anyone seen this problem?

like image 481
Tim Regan-Porter Avatar asked Nov 14 '22 00:11

Tim Regan-Porter


1 Answers

I just updated an app from Rails 2.3.10 to 2.3.11 and I ran into this bug, too.

In our code, we have:

      rate_plan = lodging.rate_plans.find_or_create_by_primary_code_and_secondary_code(rate_plan_code, inv_type_code)

which worked fine under 2.3.10. Under 2.3.11, rate_plan winds up being a new record, even though find_by_primary_code_and_secondary_code(rate_plan_code, inv_type_code) will find an existing record. Not only is rate_plan a new record in 2.3.11, but it's not saved because our uniqueness validation isn't met.

Ugh. I'll go back to 2.3.10 for now.

like image 80
Cliff Matthews Avatar answered Dec 29 '22 04:12

Cliff Matthews