Is there a way to do a “save” to an existing record instead of using update_attributes?
Half of the values I’m saving are calculated from user inputs and so are not present in the params hash. Also, there can be multiple user review cycles, which means that :id drops out of the params hash (I’m saving it in the sessions hash).
To me it seems conceptually simpler to “save” on the final version of @post. I ended up saving the final version of @post in an attributes hash, then going back to the database to get the original record, then doing update_attributes. Hopefully that 2nd retrieval of the record is cached? Actually now it’s easy to generate a list of changes in a given edit, so maybe I’ll stay with this if it works, but it seems awkward.
What is the “Rails Way?” I’m new around here and want to fit in.
<form is submitted>
@post = Post.new(params[:post])
<lots of calculations and validity checking>
finalattrhash = @post.attributes
@post = nil
@post = post.find(session[:postid])
respond_to do |format|
if @post.update_attributes(finalattrhash)
session[:postid] = nil
format.html { redirect_to(@post, :notice => 'post was successfully updated.') }
else ... end
end
Your complex handling and validations should be done inside the model. A fat controller is almost always worse than a fat model.
To make it clear, let’s make an example.
Suppose you have a model
Post. You havetitleandcontentstored in the database. And suppose you don’t want the use to directly input those fields, but other four fields: trip_name, trip_date, visited and with_who. (Of course it is not very ‘real case’ :D)So your form would give you the following hash:
This should be a normal simple form and the controller would be the simplest form too:
As all those complex logics and validations are related to the model itself, it is best to keep inside the model. In this way, your controller and view would be very clean.
===== UPDATED =====
If my understanding is correct, I would guess you have a form with two buttons (one is
reviewand one isfinalize). And for review, you just update the fields, without saving to the database.So this would be easier to give the two submit buttons a different
nameattribute. And in your controller:This part seems a little bit tricky. As the params[:action] could be one value in one time, so you won’t mess up the checking.
So if it is finalize, you just call the update_attributes to save it. Else, you assign those attributes without saving, and then check if it is valid.
However, you have to update the Post model’s code a little bit:
So that the handling would be done before you call
@post.valid?in review part. (This should not affect the finalize part)