Class: RuboCop::Cop::Appdev::NoMassAssignment

Inherits:
Base
  • Object
show all
Defined in:
lib/rubocop/cop/appdev/no_mass_assignment.rb

Overview

Forbids mass-assignment ActiveRecord APIs so authors demonstrate attribute-by-attribute assignment instead.

Scoped to ‘app/controllers/*/.rb` and `app/models/*/.rb` via `Include:` in default.yml. Combined with a receiver-shape heuristic to dodge false positives on `Hash#update`, `Array.new`, etc.

Class-method rules (‘.new` / `.create` / `.create!`):

flag only when receiver is a constant not in the `NonARConstants` allowlist.

Instance-method rules (‘.update` / `.update!` / `.assign_attributes` / `.attributes=`):

flag when receiver is an instance variable, or a local whose name
does not hint at a hash (`hash`, `map`, `dict`, `params`).

Examples:

# bad
Movie.new(:title => "x")
Movie.create({ :title => "x" })
@movie.update(:title => "x")
@movie.assign_attributes(h)
@movie.attributes = h

# good
the_movie = Movie.new
the_movie.title = params.fetch("query_title")
the_movie.save

Constant Summary collapse

MSG =
"Don't use `%<method>s` with arguments — assign attributes one at a time so students see each write."
CLASS_METHODS =
[:new, :create, :create!].freeze
INSTANCE_METHODS =
[:update, :update!, :assign_attributes, :attributes=].freeze
RESTRICT_ON_SEND =
(CLASS_METHODS + INSTANCE_METHODS).freeze
NON_AR_LOCAL_PATTERN =
/hash|map|dict|params/i

Instance Method Summary collapse

Instance Method Details

#on_send(node) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/rubocop/cop/appdev/no_mass_assignment.rb', line 40

def on_send(node)
  return if node.arguments.empty?

  case node.method_name
  when *CLASS_METHODS
    return unless constant_receiver?(node.receiver)
    return if non_ar_constant?(node.receiver)
  when *INSTANCE_METHODS
    return unless likely_ar_instance?(node.receiver)
  end

  add_offense(node, message: format(MSG, method: node.method_name))
end