Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

find_first fails with "undefined method first" #1

Open
olance opened this issue Aug 26, 2014 · 2 comments · May be fixed by #3
Open

find_first fails with "undefined method first" #1

olance opened this issue Aug 26, 2014 · 2 comments · May be fixed by #3

Comments

@olance
Copy link

olance commented Aug 26, 2014

I'm trying to use cequel-devise with... Devise ^^

I have a User model:

# -*- encoding : utf-8 -*-
class User
  include Cequel::Record

  devise :database_authenticatable, :registerable

  key :email, :varchar
  column :username, :varchar
  column :encrypted_password, :varchar
  timestamps
end

Partitioning with the email seemed to me the best way to integrate with Devise, which will be able to efficiently look for a user by email.

Signing up goes well, but when I try to log in, I end up with the following error:

NoMethodError: undefined method `first' for #<User email: "username@email.com">

The error is located here: orm_adapter-cequel (1.0.1) lib/cequel/record/orm_adapter.rb:61:in 'find_first'.

From what I've gathered, find_first tries to build a scope using the given options to query the DB and to get the first record by calling first on that scope.

scope is assigned the following values:

  • scope = klass.all #=> User
  • scope = apply_secondary_index_scope(scope, conditions) || apply_primary_key_scope(scope, conditions) #=> User['username@email.com'] => #<User:0x007f8bc4d0e6c8>

conditions only contains an email key with value username@email.com. In the second step, this resolves to applying this key as a "primary key scope", which ends up restricting the scope to a single User instance.

I guess it's because of this behavior of #[] (from cequel/cequel:lib/cequel/record/record_set.rb):

    # If {#[]} is used successively to specify all of the columns of a primary
    # key, the result will be a single {Record} or a {LazyRecordCollection},
    # depending on whether multiple values were specified for one of the key
    # columns. In either case, the record instances will be unloaded.

Because of my relational-like table, where a partition key (email) always maps to a single User instance, #[] will always return a single Record instance.
I guess find_first should call first on the returned scope only if scope is an instance of RecordSet?

@olance olance linked a pull request Aug 26, 2014 that will close this issue
@laczar
Copy link

laczar commented Nov 23, 2014

any solution on this?

@olance
Copy link
Author

olance commented Nov 23, 2014

@thelaczar I have proposed a fix in my PR #3 — you could maybe chime in there! ^^

I'm already using this fix in production without any problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants