Advanced Rails - Building Industrial-Strength Web Apps in Record Time

(Tuis.) #1
RESTful Rails | 229

Now we have to fix a small glitch due to differences between ActiveRecord and
ActiveResource. Unlike ActiveRecord objects, ActiveResource objects don’t know
their potential set of attributes when they are initialized (as that would take a web
service call to determine). In our client application, theProductsController#new
action sets up an emptyProduct with the following:


@product = Product.new

On the server,@productis anActiveRecord::Baseobject. That statement fetches
some metadata about the products table’s columns, their data types, and their con-
straints. On the other hand, on the client,@productis anActiveResource::Base
object. Initializing it with.newdoes not contact the server, and therefore it knows
nothing about its own attributes.


To resolve this, we will cheat a little. Theapp/views/products/new.erbview accesses
the product’s attributes withtext_field and the like:


<% form_for(:product, :url => products_path) do |f| %>
<p>
<b>Name</b><br />
<%= f.text_field :name %>
</p>

...
<% end %>

These methods are helpful; they will use the@productobject if it is present (and use
its attribute values as default values in the text boxes). However, if@productisnil,
the helpers will not complain and will just render empty input fields. So, we can get
away with not initializing@productat all. Simply comment out the line initializing
@product, and the situation will be resolved:


# GET /products/new
# GET /products/new.xml
def new
#@product = Product.new

respond_to do |format|
format.html # new.erb
format.xml { render :xml => @product }
end
end

Now we start the client’s web server on port 3000 (with the web service’s web server
still running on port 4000):


$ cd products_example_client
$ script/server

Loading uphttp://localhost:3000/productsin the browser, the application looks and
behaves the same, but it is backed by a RESTful connection over HTT Prather than a
SQL connection.

Free download pdf