Comments (16)
Actually, find_by_field
is being deprecated in Rails 4.
In rails 4, two other methods were added: find_by
and find_by!
. The find_by method is defined like this:
def find_by(*args)
where(*args).take
end
Now, take
differs from first
in regards to order. first
returns the first record according to the order of the primary key while take
returns whatever the database spits out first.
So while using where().take
is equivalent to find_by
and choosing whether to use one of the other is a matter of taste, where().first
differs from find_by
in a subtle and not so obvious way.
from rails-style-guide.
The following are not equivalent:
# bad
User.where(id: id).take
# good
User.find(id)
If the id doesn't exist, the first one returns nil, while the second one throws a ActiveRecord::RecordNotFound exception.
from rails-style-guide.
Worth noting find_by_field(value)
and where(field: value)
are two different operations resulting in different SQL queries.
find_by_field(value)
SQL has LIMIT 1
applied so will be much more efficient than where(field: value)
- I would argue that these are not interchangeable and should be used in different circumstances.
If you expect a AR record to exist or not, ie binary decision, yes/no, use find_by_field
otherwise if you expect many, irrespective of whether you want 1 or more, use where(field: value)
.
If you apply .first
to where()
then the SQL is ordered by primary key and LIMIT 1
applied which may be different to what you expect.
from rails-style-guide.
See https://github.com/bbatsov/rails-style-guide#find_by
from rails-style-guide.
So let's talk about style, not deprecation 😸
from rails-style-guide.
Actually, they are not deprecated.
https://github.com/rails/activerecord-deprecated_finders
'Note that find(primary_key), find_by..., and find_by...! are not deprecated.'
from rails-style-guide.
I swear I remember reading that find_by_field
was being deprecated. You're right though.
So it seems now (in Rails 4) we have 3 ways to do the same thing:
find_by_field(value)
find_by(field: value)
where(field: value).take
And there's a fourth way that's subtly different:
where(field: value).first
from rails-style-guide.
@guilhermesimoes I'm 100% certain find_by_field
is not deprecated in Rails 4.
from rails-style-guide.
Yes, I'm 100% certain now too. What was deprecated was using dynamic finders with conditions, like: Post.find_by_title('Rails', conditions: { author: 'admin' })
, thus my confusion.
So, what's your opinion on the preferred way of finding something?
from rails-style-guide.
find_by_field(value)
looks more readable for me.
from rails-style-guide.
@kukula in case if simple predicate - yes, it's more readable. But in real world sometimes it's okay to work with cases like this:
# this
Order.find_or_create_by_user_id_and_item_id(@user.id, @item.id)
# or this
Order.where(:user => @user, :item => @item).find_or_create
So, what variant is more readable for you now? :)
from rails-style-guide.
@pechorin I'm not talking about deprecated finders. I'm talking about find_by_field(value)
vs where(field: value).first
from rails-style-guide.
according to http://edgeguides.rubyonrails.org/4_0_release_notes.html#extraction-of-features-to-gems the majority of dynamic finders are being moved to an external gem. Here is a specific note that shows All dynamic methods except for find_by_... and find_by_...! are deprecated.
find_all_by_...
can be rewritten using where(...)
find_last_by_...
can be rewritten using where(...).last
scoped_by_...
can be rewritten using where(...)
The preferred method is where(field: value).first
from rails-style-guide.
Great! Thank you @bbatsov !
from rails-style-guide.
@xinspire And if id is a out of range value User.find(id)
will raise ActiveRecord::RecordNotfound
, but User.where(id: id).take
will raise ActiveModel::RangeError
see gitlab 500 https://gitlab.com/coldnight/ci-test/issues/464444444444444444444444444444444444
from rails-style-guide.
just extra 2 cents here where(x).first
adds that implicit ORDER BY primary_key ASC LIMIT 1
that might be a hit on performance, whereas find_by
just adds LIMIT 1
to the query and no ordering is happening
from rails-style-guide.
Related Issues (20)
- 7 Standard Controller Actions HOT 11
- Use more specific predicates instead of vague `blank?` and `present?` HOT 2
- Per attribute validations
- Prefer `ActionDispatch::IntegrationTest` over `ActionController::TestCase`
- Better docs for `dependent: :destroy` HOT 1
- Where with Ranges: "good" vs "bad" are not equivalent HOT 3
- Description of Single Attribute Validations seems wrong. HOT 1
- Suggestion: Avoid `render ... and return` HOT 4
- Suggestion: Use string literals instead of named routes or URL helpers in tests HOT 2
- Add delete_all to the list of methods that skip model validations HOT 2
- Cop idea: prefer symbol proc to `if:` and `unless:` filter lambdas HOT 2
- Are blank routes preferred or routes with `/`
- Suggestion: Add notes about `.none()` HOT 1
- Suggestion: Add notes about returned value of ActiveRecord transaction
- Suggestion: Add description about Active Record redundant `all` HOT 1
- Suggestion: don't divide `.where.not` into two lines
- Suggestion: 3-state booleans don't require a default HOT 3
- "Redundant `all`" is too naive HOT 10
- Cop idea: merge `.first` || `.create!` into `.first_or_create!` HOT 6
- Cop idea: Prefer `assert_raises` over `assert_raise` HOT 10
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rails-style-guide.