How do I cache ActiveRecord model objects across redirects?
This is possibly a newbie question, but I'm not sure what terms to search for.
Say I have a CUSTOMER object, and I want to send a MESSAGE to that customer.
What I would do first is add a SENDMESSAGE action on the CUSTOMER controller, which builds the message object. (Assu开发者_如何转开发me this is the right thing to do?)
In this instance however, rather than actually send the message from within this action, I need to forward to the edit view of the MESSAGE to capture the body text etc.
The question: I want to do this without persisting the object. I want to build the object here and then hand it over to another view for completion.
def sendmessage
@message = Message.new
@message.title = 'WIBBLE'
@message.thecustomer = self
@message.save
respond_to do |format|
format.html { redirect_to(edit_message_path(@ message)) }
format.xml { render :xml => @ message }
end
end
Maybe my question boils down to, what is the 'rails way' to cache parameters and objects across requests and multiple screens.
Happy to be pointed towards Web URLs as I expect this is simple.
Thanks
The standard way to persist data across requests when building Web applications is to use the HTTP session. Rails makes an implicit session hash available for this purpose. It's used like this:
session[:message] = @message #store
@message = session[:message] #retrieve
You can also use the Rails flash session wrapper for passing information from the current action to the next. It's usually used for storing text to be displayed in the UI, but you can use it for persisting any object:
flash[:message] = @message #store
@message = flash[:message] #retrieve
In both cases, the objects that you're storing must be serializable. Note that by default Rails stores session data in an encrypted cookie on the client; consider it a strong hint that storing a lot of data in the session is frowned upon in the Rails world.
The is actually a pretty common task that you're over complicating. The Rails way to handle this is not to persist the object in question, but instead just render the view that will complete the action.
class CustomersController < Application Controller
def sendmessage
@message = Message.new
@message.title = 'WIBBLE'
@message.thecustomer = self
respond_to do |format|
format.html { render "messages/edit" }
format.xml { render :xml => @ message }
end
end
end
In general persisting whole objects across HTTP requests in Rails is a bad idea, the only real way to do it is to is to through the session or flash hash as John Topley suggests, but both of those are limited in the amount of space available. Which is why François Beausoleil suggests to only store the object id in the session. Either way you should clear either hash when you're done with it.
What you should be doing here, is designing your controller actions such that each action fully completes a task. Completing half a task and redirecting so a second action can complete the task may be slightly more DRY, but, it doesn't gel well with the Rails control flow. As the example shows, the controller action completes all the processing required to render the view.
Essentially if you're looking to preserve information because you're redirecting. You will find it easier to render the view you're redirecting to.
精彩评论