2015-11-18 2 views
0

Любопытно, если кто-то знает тонкости find_by, так как я проверил документацию и не смог найти информацию.Rails `find_by` возвращает огромный ID

Я знаю, что find Используется, чтобы найти по основным ключам, таким как: @user = User.find(params[:id]), вернув правильный пользователь.

Прежде чем я исправил свой код, он был @user = User.find_by(params[:id]) и возвратил пользователя с идентификационным способом, превышающим число пользователей в моей БД.

Может ли кто-нибудь помочь мне понять, что происходит под капотом? Что ищет find_by по умолчанию, когда параметр опущен, который возвращает этот странный пользовательский объект?

ответ

0

find_by_field(value) равнозначно where(field: value), но не предполагается использовать без добавления имени поля к методу, как вы упомянули. Кроме того, он возвращает только первое совпадающее значение. Например, вместо того, чтобы делать User.where(name: 'John').limit(1) вы можете использовать: User.find_by_name 'John'.

С моей стороны, используя find_by с PostgreSQL выдает ошибку, когда find_by_id делает работу:

User.find_by(1) 
SELECT "users".* FROM "users" WHERE (1) ORDER BY "users"."email" ASC LIMIT 1 
PG::DatatypeMismatch: ERROR: argument of WHERE must be type boolean, not type integer 

User.find_by_id 1 
SELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."email" ASC LIMIT 1 
<User id: 1, ... 

User.where(id: 1) # note that there is no LIMIT 1 in the generated SQL 
SELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."email" ASC 

Вы можете использовать камень query_tracer, чтобы увидеть сгенерированный SQL или проверить эту thread.

0

Просьба посмотреть here.

Вот выдержка для find_by:

находит первую запись, соответствующую заданным условиям. Нет никакого подразумеваемого заказа, поэтому, если порядок имеет значение, вы должны указать его сами.

Если запись не найдена, возвращается nil.

Post.find_by name: 'Spartacus', rating: 4 
Post.find_by "published_at < ?", 2.weeks.ago 

Это то, что вы искали?


UPDATE

User.find_by(3)equivalent является для User.where(3).take Вот вывод из консоли

pry(main)> User.where(3).take 
#=> User Load (0.3ms) SELECT `users`.* FROM `users` WHERE (3) LIMIT 1 
+0

Спасибо за облегчающий ответ, но не совсем. Специфично для моего приложения, params [: id] = 3, поэтому 'User.find (3)' найти правильного пользователя (3). Однако 'User.find_by (3)' возвращает пользователя с идентификатором 409608538 (путь больше, чем у 100 пользователей семян у меня есть), поэтому мне было просто интересно, как это происходит – Splice114

+0

попробуйте User.find_by (id: 3). Что в итоге? – bosskovic

+0

btw, я не могу воспроизвести то, что вы упомянули в консоли; User.find (3), User.find_by (3), User.find_by (id: 3) все возвращают одинаковый, правильный пользователь. Можете ли вы включить в свой вопрос какую-то копию-вставку с консоли? – bosskovic

0

Это выглядит как рельсы вернуться к вам идентификатору объекта в памяти. Это как запрос User.find(params[:id]).object_id. Но почему это происходит? Я стараюсь делать то же самое в своем приложении с версией 4.2.4, и все идет хорошо