# Using update to either update or create new object

**URL:** <https://www.ruby-forum.com/t/using-update-to-either-update-or-create-new-object/158599>\
**Category:** Rails\
**Created:** [January 25, 2009, 6:51pm UTC](https://www.ruby-forum.com/t/using-update-to-either-update-or-create-new-object/158599 "2009-01-25T18:51:06Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![david](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/aeb1de/32.png) [@david](https://www.ruby-forum.com/u/david)\
**Post date:** [January 25, 2009, 6:51pm UTC](https://www.ruby-forum.com/t/using-update-to-either-update-or-create-new-object/158599/1 "2009-01-25T18:51:06Z")

</div>

I’m using form\_remote\_for to create a new object in the beginning, and  
then if the object already exists, update it. I’m using the REST form  
so my form looks like this:

\<% form\_remote\_for(@spec) do |form| %\>  
\<% end %\>

with the controller defining the @spec object like so:  
@spec = (@user.spec ||= Spec.new)

I’m not sure if this is the best way, but my main question lies in the  
implementation of the update action in the spec controller which is  
called when the form is submitted. This definitely needs to be  
refactored and I could use some help with the best way:  
I also created a pastie, which is much easier to read:  
[http://pastie.org/370302](http://pastie.org/370302)

def update  
respond\_to do |format|  
if logged\_in\_user.spec.nil?  
@spec = Spec.new(params[:spec])  
@spec[“user\_id”] = logged\_in\_user.id  
if @spec.save  
format.js do  
render :update do |page|  
page.form.reset ‘login\_form’  
page.redirect\_to user\_path(logged\_in\_user)  
end  
end  
else  
format.js do  
render :update do |page|  
page \<\< “$(‘message\_popup’).popup.show();”  
end  
end  
end  
else  
if logged\_in\_user.spec.update\_attributes(params[:spec])  
format.js do  
render :update do |page|  
page.redirect\_to user\_path(logged\_in\_user)  
end  
end  
else  
format.js do  
render :update do |page|  
page \<\< “$(‘message\_popup’).popup.show();”  
end  
end  
end  
end  
end  
end

---

<div class="post-metadata">

**Author:** ![david](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/aeb1de/32.png) [@david](https://www.ruby-forum.com/u/david)\
**Post date:** [January 25, 2009, 7:41pm UTC](https://www.ruby-forum.com/t/using-update-to-either-update-or-create-new-object/158599/2 "2009-01-25T19:41:02Z")

</div>

David wrote:

> with the controller defining the @spec object like so:  
> @spec = (@user.spec ||= Spec.new)

That’s just || not ||=. Why didn’t your unit tests catch that?

> ```
> @spec["user_id"] = logged_in_user.id
> 
> ```

Why not logged\_in\_user.spec.build(params[:spec])

> ```
> if @spec.save
> format.js do
> 
> ```

You can move the format.js do line up to just after respond\_to. It can  
wrap all  
of this…

> ```
> render :update do |page|
> page.form.reset 'login_form'
> page.redirect_to user_path(logged_in_user)
> 
> ```

Why are you clearing the form and immediately going to another page?

(Firefox has a “feature” where they preserve form contents. Are you  
wisely  
thwarting that?)

> ```
> end
> end
> else
> format.js do
> render :update do |page|
> page << "$('message_popup').popup.show();"
> 
> ```

Shouldn’t that push the errors into the popup?

> ```
> end
> end
> end
> else
> if logged_in_user.spec.update_attributes(params[:spec])
> 
> ```

Can’t this just be part of the new and save bit above? Otherwise all the  
code  
below it is the same.

> ```
> end
> end
> end
> 
> ```
> 
> end  
> end

Your unit tests should make that very easy to refactor. Just change one  
line at  
a time and pass all the tests after each change!

–  
Phlip
