# Update\_attributes...more efficient replacement

**URL:** <https://www.ruby-forum.com/t/update-attributes-more-efficient-replacement/112943>\
**Category:** Rails\
**Created:** [August 24, 2007, 7:36pm UTC](https://www.ruby-forum.com/t/update-attributes-more-efficient-replacement/112943 "2007-08-24T19:36:55Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![ericgoodwin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/c68b51/32.png) [@ericgoodwin](https://www.ruby-forum.com/u/ericgoodwin)\
**Post date:** [August 24, 2007, 7:36pm UTC](https://www.ruby-forum.com/t/update-attributes-more-efficient-replacement/112943/1 "2007-08-24T19:36:55Z")

</div>

I was browsing through the Rails Docs, looking for a better way to do  
updates.

When you use update\_attributes, it saves all the attributes from the  
object. I have some objects with very large text fields which means a  
lot data going forth and back.

I was looking for a cleaner way. I created a wrapper for the update\_all  
method, which uses straight sql to do updates. So now, I can do  
user.update\_attributes\_with\_sql(:some\_field=\>some\_value), like I would  
with update\_attributes, only it updates only the fields that I want.

Am I reinventing the wheel here? I couldn’t find any function to this in  
AR.

I extended ActiveRecord with this:

```
  def update_attributes_with_sql(attrs) # allows you to update

```

individual columns without saving the whole record (also much faster)  
self.class.update\_with\_sql(id, attrs)  
self.attributes = attrs  
end

```
  def self.update_with_sql(id, attrs)
     conditions = id.is_a?(Array) ? "id IN (#{id.join(', ')})" :

```

“id=#{id}”  
update\_all sanitize\_sql\_hash\_for\_set(attrs), conditions  
end

```
  def self.sanitize_sql_hash_for_set(attrs)
     # just need to replace the join with ', 'instead of AND
     conditions = attrs.map do |attr, value|
        "#{table_name}.#{connection.quote_column_name(attr)}

```

#{attribute\_condition(value)}"  
end.join(’, ')

```
     replace_bind_variables(conditions, attrs.values)
  end
```

---

<div class="post-metadata">

**Author:** ![ericgoodwin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/c68b51/32.png) [@ericgoodwin](https://www.ruby-forum.com/u/ericgoodwin)\
**Post date:** [August 24, 2007, 7:59pm UTC](https://www.ruby-forum.com/t/update-attributes-more-efficient-replacement/112943/2 "2007-08-24T19:59:40Z")

</div>

Aryk G. wrote the following on 24.08.2007 19:36 :

> with update\_attributes, only it updates only the fields that I want.
> 
> Am I reinventing the wheel here? I couldn’t find any function to this in  
> AR.

I toyed with this idea too but didn’t follow through because of  
validation.

Without proper locking you should know that you break one important  
assumption AR does when validating: the in-memory object validated is  
actually what will be stored in DB. Your current code doesn’t support  
validation and probably won’t properly unless you add at least  
optimistic locking support.

Lionel.

---

<div class="post-metadata">

**Author:** ![ericgoodwin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/c68b51/32.png) [@ericgoodwin](https://www.ruby-forum.com/u/ericgoodwin)\
**Post date:** [August 24, 2007, 9:20pm UTC](https://www.ruby-forum.com/t/update-attributes-more-efficient-replacement/112943/3 "2007-08-24T21:20:10Z")

</div>

Lionel,

That’s a good point you make. It’s true, that if you are saving form  
data, validations are super important.

Im not saying to replace update\_attributes, but sometimes I just want a  
lean straight-to-the-point insert into the database.

I guess you can never be completely sure about needing validation for  
the attributes you are updating, but if you are pretty certain about  
what you are inserting, it can save a lot of overhead. For example, if I  
want to update {:updated\_at=\>Time.now}, you don’t need to resave all the  
objects.

Lionel B. wrote:

> Aryk G. wrote the following on 24.08.2007 19:36 :
> 
> > with update\_attributes, only it updates only the fields that I want.
> > 
> > Am I reinventing the wheel here? I couldn’t find any function to this in  
> > AR.
> 
> I toyed with this idea too but didn’t follow through because of  
> validation.
> 
> Without proper locking you should know that you break one important  
> assumption AR does when validating: the in-memory object validated is  
> actually what will be stored in DB. Your current code doesn’t support  
> validation and probably won’t properly unless you add at least  
> optimistic locking support.
> 
> Lionel.
