class RuboCop::Cop::Rails::FindById
This cop enforces that `ActiveRecord#find` is used instead of `where.take!`, `find_by!`, and `find_by_id!` to retrieve a single record by primary key when you expect it to be found.
@example
# bad User.where(id: id).take! User.find_by_id!(id) User.find_by!(id: id) # good User.find(id)
Constants
- MSG
- RESTRICT_ON_SEND
Public Instance Methods
on_send(node)
click to toggle source
# File lib/rubocop/cop/rails/find_by_id.rb, line 40 def on_send(node) where_take?(node) do |where, id_value| range = where_take_offense_range(node, where) bad_method = build_where_take_bad_method(id_value) register_offense(range, id_value, bad_method) end find_by?(node) do |id_value| range = find_by_offense_range(node) bad_method = build_find_by_bad_method(node, id_value) register_offense(range, id_value, bad_method) end end
Private Instance Methods
build_find_by_bad_method(node, id_value)
click to toggle source
# File lib/rubocop/cop/rails/find_by_id.rb, line 83 def build_find_by_bad_method(node, id_value) case node.method_name when :find_by_id! "find_by_id!(#{id_value.source})" when :find_by! "find_by!(id: #{id_value.source})" end end
build_good_method(id_value)
click to toggle source
# File lib/rubocop/cop/rails/find_by_id.rb, line 75 def build_good_method(id_value) "find(#{id_value.source})" end
build_where_take_bad_method(id_value)
click to toggle source
# File lib/rubocop/cop/rails/find_by_id.rb, line 79 def build_where_take_bad_method(id_value) "where(id: #{id_value.source}).take!" end
find_by_offense_range(node)
click to toggle source
# File lib/rubocop/cop/rails/find_by_id.rb, line 71 def find_by_offense_range(node) range_between(node.loc.selector.begin_pos, node.loc.expression.end_pos) end
register_offense(range, id_value, bad_method)
click to toggle source
# File lib/rubocop/cop/rails/find_by_id.rb, line 58 def register_offense(range, id_value, bad_method) good_method = build_good_method(id_value) message = format(MSG, good_method: good_method, bad_method: bad_method) add_offense(range, message: message) do |corrector| corrector.replace(range, good_method) end end
where_take_offense_range(node, where)
click to toggle source
# File lib/rubocop/cop/rails/find_by_id.rb, line 67 def where_take_offense_range(node, where) range_between(where.loc.selector.begin_pos, node.loc.expression.end_pos) end