I just did this myself so let me try:
there are many ways to do preview. The way I’m doing it, I’m showing
the preview in all its glory and show the filled in form on the same
page so user can edit it some more or submit it.
main thing to realize is you can use the same new and edit view you
are using now and call the same actions. I’ll tackle previewing the
edit of an existing post first.
First add a preview button to the form e.g.,
In my PostsController’s update method (my message model is Post,
obviously)
find @post as usual
def update
@post = Post.find(params[:id])
if params[:submit] == ‘Preview’
@post.attributes = params[:post]
preview( ‘edit’)
return
end
do usual thing for rest of it
,
If you look at your update method, normally you do something like this
@post = Post.find(params[:id])
if @post.update_attributes(params[:post])
…
but you don’t want to update_attributes, which saves it to the DB.
You just want to copy them from the form, which is exactly what
@post.attributes = params[:post]
does. That’s what you probably got stuck on. How did I figured that
out? I just googled rails update_attributes and found
http://railsmanual.com/class/ActiveRecord::Base/update_attributes
and it shows me
def update_attributes(attributes)
self.attributes = attributes
save
end
That’s exactly what I need to do, without the save.
Here’s my preview method (nothing magical about the name preview, just
the obvious name), which I put under protected b/c it shouldn’t be
called from outside
protected
def preview( action)
@preview = @post.valid?
render :action => action
end
this sets a variable called @preview to true if post is valid.
Calling @post.valid? validates your post w/o saving it. If there are
errors, it’ll set the error msgs that you display in your form, e.g.
<%= error_messages_for :post %>
Then I just render the action I passed, i.e., render :action => ‘edit’
which renders ‘posts/edit.rhtml’
In posts/edit.rhtml, I added this above the form
<%= if defined?( @preview) && @preview %>
… display post …
<% end %>
How you display the post is up to you. To test, you can just do
something simple like this to verify it’s working
<%= h(@post.title) %>
<%= h(@post.body) %>
what I ended up doing was extract the code to display a post from
show.rhtml and use render=>:partial to display it.
<%= render :partial => ‘shared/post’, :layout => true,
:locals => { :post => @post, :preview => true } %>
Note that I’m passing the @post variable as well as setting a preview
vaiable to true b/c inside the partial I need to suppress certain
features when showing a preview.
That’s it. What about when creating a new post? Just do this:
def create
@post = Post.new(params[:post])
if params[:submit] == ‘Preview’
preview( ‘new’)
return
end
rest unchanged …
Same thing as edit, but I’m just creating a new post with attributes
from the form’s post, and I go and render new.rhtml again. My
new.rhtml has the same added code as edit.rhtml. I guess I could
refactor some more and have just one view for both new and edit, but
hey…
Note: if the post doesn’t validate, I don’t show the preview. But you
could show the preview anyway if you want to.
here’s one article on doing AJAX preview
http://www.railsdiary.com/diary/ajax_markdown_preview
hope that helps. If anybody sees something wrong, pls let me know.
On Dec 14, 5:11 am, Bob S. [email protected]