GithubHelp home page GithubHelp logo

Comments (16)

guilhermesimoes avatar guilhermesimoes commented on May 10, 2024 12

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.

xinspire avatar xinspire commented on May 10, 2024 10

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.

rob-murray avatar rob-murray commented on May 10, 2024 9

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.

bbatsov avatar bbatsov commented on May 10, 2024 7

See https://github.com/bbatsov/rails-style-guide#find_by

from rails-style-guide.

kukula avatar kukula commented on May 10, 2024 5

So let's talk about style, not deprecation 😸

from rails-style-guide.

kukula avatar kukula commented on May 10, 2024

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.

guilhermesimoes avatar guilhermesimoes commented on May 10, 2024

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.

bbatsov avatar bbatsov commented on May 10, 2024

@guilhermesimoes I'm 100% certain find_by_field is not deprecated in Rails 4.

from rails-style-guide.

guilhermesimoes avatar guilhermesimoes commented on May 10, 2024

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.

kukula avatar kukula commented on May 10, 2024

find_by_field(value) looks more readable for me.

from rails-style-guide.

pechorin avatar pechorin commented on May 10, 2024

@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.

kukula avatar kukula commented on May 10, 2024

@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.

blairanderson avatar blairanderson commented on May 10, 2024

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.

kukula avatar kukula commented on May 10, 2024

Great! Thank you @bbatsov !

from rails-style-guide.

fffx avatar fffx commented on May 10, 2024

@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.

lanadz-shopify avatar lanadz-shopify commented on May 10, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.