Rails: find и find_by возвращают странный #‹User:0x10b7b82c8› в модели, но не в консоли rails

Странная проблема, над которой я застрял уже несколько часов:

Я пишу простой пользовательский логин с использованием Rails 3, где пользователь входит в систему со своим адресом электронной почты и паролем. В моей модели пользователя я пытаюсь найти правильный объект пользователя по его электронной почте, а затем продолжаю проверять, ввели ли они правильный пароль.

Когда я пытаюсь найти пользователя из консоли rails

>> User.find_by_email("[email protected]")

Я получаю желаемый результат - возвращается правильный объект User

  User Load (0.7ms)  SELECT `users`.* FROM `users` WHERE `users`.`email` = '[email protected]' LIMIT 1  
=> #<User id: 21, first_name: "Test", last_name: "Man", hashed_password: "ca630762c6dce11af5a9923c7955131f8d6f7a16", cell_phone_number: nil, email: "[email protected]", created_at: "2012-12-13 14:35:38", updated_at: "2012-12-13 14:35:38", salt: nil, is_admin: false>

Но когда я помещаю следующий фрагмент кода в файл model/user.rb, я получаю странный результат.

user = User.find_by_email("[email protected]")
puts "******** user = #{user}"

Выводит следующее:

******** user = #<User:0x10b7b82c8>

Когда я пытаюсь использовать эту пользовательскую переменную, она выдает ошибку и говорит, что переменная или метод «пользователь» неизвестен.

Вот вывод из файла журнала:

Started POST "/users/login_attempt" for 127.0.0.1 at Thu Dec 13 08:40:47 -0600 2012
                            Processing by UsersController#login_attempt as HTML
                              Parameters: {"password"=>"[FILTERED]", "utf8"=>"", "email"=>"asdf", "authenticity_token"=>"4xeLxpSb4GidsHUIe4b55LhOVJtDEiv5UaQYU9aBv5k=", "commit"=>"Log In"}
                              User Load (0.4ms)  SELECT `users`.* FROM `users` WHERE `users`.`email` = '[email protected]' LIMIT 1

Вот несколько вещей, которые я пробовал...

  1. запрос mysql выше определенно работает. Я скопировал его в mysql, и он вернул правильного пользователя.

  2. Я пробовал найти (id), который также не работает. Возвращает аналогичного пользователя: 0x10b7b82c8

В целом, я не могу понять, почему консоль выдает другой результат, чем сам код модели.

Кто-нибудь знает, почему я получаю такой странный результат от find_by?

Большое спасибо!

Изменить: вот дополнительный код, так как Фредерик упомянул, что его недостаточно, чтобы найти проблему.

Из контроллеров/users_controller.rb

class UsersController < ApplicationController


  def login
  end

  def login_attempt

    authorized_user = User.authenticate(params[:email], params[:password])

      redirect_to({:controller => 'records', :action => 'list'} )

  end



  def new
@user = User.new
  end 

  def create
@user = User.new(params[:user])

    if @user.save
      redirect_to({:controller => 'records', :action => 'list'} )

    else
      render('new')
end

end



end

из моделей/user.rb

require 'digest/sha1'

class User < ActiveRecord::Base

attr_accessible :password, :password_confirmation, :email, :email_confirmation, :first_name, :last_name

attr_accessor :password


before_save :create_hashed_password
after_save :clear_password

# only on create, so other attributes of this user can be changed

#create method to authenticate login credentials
def self.authenticate(email,password)

  user = User.find_by_email("[email protected]")

  puts "******** user = #{user}"

end

#method to check provided password against password stored in db

 def password_match?(password="")

     newuser.hashed_password == hash_password(password)

 end


#hash_password adds salt to password and encrypts it
def self.hash_password(password="")
    salted_pw = password + PW_SALT
    hashed_pw = Digest::SHA1.hexdigest(salted_pw)       
end

  private

  def create_hashed_password
    # Whenever :password has a value hashing is needed
    unless password.blank?
     # self.hashed_password = User.hash_password(password)
     self.hashed_password = User.hash_password(password)
    end
  end

  def clear_password
    # for security and b/c hashing is not needed
    self.password = nil
  end




end

person corbin    schedule 13.12.2012    source источник
comment
Это одно и то же: единственное отличие состоит в том, что консоль отображает объекты, вызывая для них inspect, тогда как использование интерполяции строк ("#{user}") вызывает to_s. Что-то подозрительное в вашем контроллере или в каком-то другом фрагменте кода, который вы не показали   -  person Frederick Cheung    schedule 13.12.2012
comment
Спасибо, Фредерик. В моей модели я изменил его, чтобы поставить user.inspect, и это дало мне тот же результат, что и консоль! Однако, когда я пытаюсь использовать этот объект, он говорит мне, что пользовательская переменная не может быть найдена. Любая идея, почему это так? Я также добавил дополнительный код выше.   -  person corbin    schedule 13.12.2012


Ответы (3)


Метод возвращает результат последнего выражения в нем. В случае вашего метода authenticate последним выражением является вызов puts, который всегда возвращает nil, поэтому

authorized_user = User.authenticate(params[:email], params[:password])

устанавливает authorized_user равным нулю, а не пользователю, полученному из базы данных.

person Frederick Cheung    schedule 13.12.2012
comment
Хороший улов, Фредерик. Спасибо за помощь! - person corbin; 13.12.2012

Если вы извлекаете экземпляр пользователя с помощью user = User.find_by_email('[email protected]'), вы возвращаете экземпляр пользователя. puts "My user: #{ user }" даст вам тот же результат, что и вызов "My user: #{ user.inspect }". Вы вызываете inspectна userэкземпляре, и результат выглядит как #<User:0x10b7b82c8>.

Я предполагаю, что вы пытаетесь отобразить какую-то информацию от пользователя.

puts "My new user: #{user.first_name} #{user.last_name}"
person Thomas Klemm    schedule 13.12.2012

User.find_by email: '[email protected]'

И если вы используете драгоценный камень Pry, он аккуратно организует его.

person sergio    schedule 16.06.2016