Skip to content

Changes, changed? and <attribute>_was explained #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions rails_tip/2016-03-31-changes_and_changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
title: Check status of ActiveRecord Object
tip-number: 30
tip-username: Surender
tip-username-profile: https://github.com/harrysuren
tip-description: We can check the status of an ```ActiveRecord``` Object and its variables by using these methods.

---


ActiveRecord keeps a sizable amount of information about an object while it undergoes updates. A hash, accessible via the changes method, acts a central location for these updates.

**```changes```**

Each key in the changes hash maps to a record’s attribute. The value of each key is an Array with two elements: what the attribute value used to be, and what it is now:

```ruby
order = Order.find(1)
order.user_id
# => 10
order.user_id = 11
order.changes
# => {"user_id"=>[10, 11]}
```

**a. ```changed?```**

A simple boolean method changed? is available to determine if anything on the object is different since its retrieval.

```ruby
order = Order.find(1)
order.user_id = 11
order.changed?
# => true
```

However, if the same value is set on a model, regardless of the value’s object_id, changed? returns false:

```ruby
order = Order.find(1)
order.user_id
# => 1
order.user_id = 1
order.changed?
# => false
```

Two “different” strings were set to book.title but since they resolve to the same characters, the object is not changed?.

When using PostgreSQL, the ```changed?``` method can save unnecessary ```begin``` and ```commit``` transaction calls for objects that have no changes:

```ruby
class OrdersController < ApplicationController
def update
@order = Order.find(order_params[:id])
@order.assign_attributes(order_params)
@order.save! if @order.changed?
end
end
```

**b. ```<attribute>_was```**

Accessing the same ```changes``` hash as the ```changed?``` method, ```<attribute>_was``` returns the value of an attribute before it was reassigned:

```ruby
order = Order.find(1)
order.status
# => 'waiting'
order.status = 'delivered'
# => 'delivered'
review.status_was
# => 'waiting'
```