ActiveRecord: Query Attributes

tl;dr
You can use attribute? as shorthanded version of attribute.present?, except for numeric attributes and associations.

Technical Details

attribute? is generated for all attributes and not only for boolean attributes.

These methods are using #query_attribute under the hood. For more details you can see ActiveRecord::AttributeMethods::Query.

In most circumstances query_attribute is working like attribute.present?. If your attribute is responding to :zero? then you have to be aware that query_attribute is responding like !zero?.

contract.savings = BigDecimal('0.0')

contract.savings?
# => false

contract.query_attribute(:savings)
# => false

contract.savings.present?
# => true

ActiveType

Virtual attributes of ActiveType are not using query_attribute. If you are using attribute? on a virtual attribute then it's using present? under the hood.

So for ActiveType you can treat attribute? as a real shorthanded version of attribute.present?.

class Human::Form < ActiveType::Record[Human]
  attribute: number_of_teeth
end

human.age = 0
human.number_of_teeth = 0

human.age?
# => false

human.number_of_teeth?
# => true

Associations

attribute? methods are not generated for associations.

Warning

Don't use query_attribute on associations. In case of Rails 7 you are getting an error. In Rails 6 this method is always responding with false.

Julian About 2 years ago