class RuboCop::Cop::Rails::BelongsTo

@see github.com/rails/rails/pull/18937<br>@see guides.rubyonrails.org/5_0_release_notes.html<br><br>end
belongs_to :blog, optional: false
class Post < ApplicationRecord
# good
end
belongs_to :blog, required: true
class Post < ApplicationRecord
# bad
end
belongs_to :blog, optional: true
class Post < ApplicationRecord
# good
end
belongs_to :blog, required: false
class Post < ApplicationRecord
# bad
@example
user can remove depending on their defaults.
‘required: true`, we’ll simply invert it to ‘optional: false` and the
superfluous `optional: false`). Therefore, in the cases we’re using
should replace it with ‘optional: false` (or, similarly, remove a
can’t say whether it’s safe to remove ‘required: true` or whether we
value of `config.active_record.belongs_to_required_by_default`, we
However, without knowing whether they’ve set overridden the default
definitely want to autocorrect to ‘optional: true`.
In the case that the developer is doing `required: false`, we
option in favor of optional for belongs_to. (Pull Request)
per-association basis with optional: true. Also deprecate required
association is not present. You can turn this off on a
belongs_to will now trigger a validation error by default if the
From the release notes:
can be controlled through the use of `optional: true`.
Since Rails 5, belongs_to associations are required by default and this
association is required via the deprecated `required` option instead.
This cop looks for belongs_to associations where we control whether the

def autocorrect(node)

def autocorrect(node)
  opt = extract_required_option(node)
  return unless opt
  lambda do |corrector|
    if match_required_true?(opt)
      corrector.replace(opt.loc.expression, 'optional: false')
    elsif match_required_false?(opt)
      corrector.replace(opt.loc.expression, 'optional: true')
    end
  end
end

def extract_required_option(node)

def extract_required_option(node)
  _, opts = match_belongs_to_with_options(node)
  return unless opts
  opts.find do |opt|
    match_required_true?(opt) ||
      match_required_false?(opt)
  end
end

def on_send(node)

def on_send(node)
  opt = extract_required_option(node)
  return unless opt
  return unless match_required_true?(opt) || match_required_false?(opt)
  message =
    if match_required_true?(opt)
      SUPERFLOUS_REQUIRE_TRUE_MSG
    elsif match_required_false?(opt)
      SUPERFLOUS_REQUIRE_FALSE_MSG
    end
  add_offense(node, message: message, location: :selector)
end