Class: RuboCop::Cop::DevDoc::Style::AvoidSend
- Inherits:
-
Base
- Object
- Base
- RuboCop::Cop::DevDoc::Style::AvoidSend
- Defined in:
- lib/rubocop/cop/dev_doc/style/avoid_send.rb
Overview
Avoid ‘send` and `public_send` with an explicit receiver.
## Rationale ‘send()` can call any method, including destructive ones like `destroy`. When the method name is dynamic, this is a real risk — a crafted parameter can invoke methods the developer never intended to expose. If `send()` is unavoidable, add safeguards to restrict which methods can be called.
## Safer alternatives
**a) For model attributes — use bracket notation instead.** ‘@model` only accesses database columns, so it cannot accidentally invoke methods like `destroy`.
❌ Dangerous — method_name could be :destroy or any other method
@user.send(method_name)
✔️ Safe — only accesses database columns
@user[method_name]
**b) For non-model objects — use a prefix to restrict callable methods.** By interpolating the dynamic part into a fixed prefix, only methods with that prefix (e.g. ‘export_csv`, `export_pdf`) can be invoked, preventing accidental calls to unintended methods.
❌ Unrestricted — any method can be called
obj.send(method_name)
✔️ Restricted — only methods with the prefix can be called
obj.send("export_#{method_name}")
**c) For known methods — call directly instead of via ‘send`.**
Constant Summary collapse
- MSG =
'Avoid `%<method>s` with an explicit receiver. ' \ 'Use bracket notation for model attributes, or restrict callable methods with a prefix.'.freeze
- RESTRICT_ON_SEND =
%i[send public_send].freeze
Instance Method Summary collapse
Instance Method Details
#on_send(node) ⇒ Object
52 53 54 55 56 |
# File 'lib/rubocop/cop/dev_doc/style/avoid_send.rb', line 52 def on_send(node) return if node.receiver.nil? add_offense(node.loc.selector, message: format(MSG, method: node.method_name)) end |