views:

358

answers:

1

I have a line in my routes.rb to map my Album model as a resource:

  map.resources :albums

However, using Datamapper in place of ActiveRecord in Rails, why would this line:

format.html { redirect_to(@album) }

cause a redirect to:

albums/%23<Album:0x72d452c>

instead of:

albums/1

In case further context is needed, my full create method from the Controller is listed here:

  def create
    @album = Album.new(params[:album])

    respond_to do |format|
      if @album.save
        flash[:notice] = 'Album was successfully created.'
        format.html { redirect_to(@album) }
        format.xml  { render :xml => @album, :status => :created, :location => @album }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @album.errors, :status => :unprocessable_entity }
      end
    end
  end

As is convention, this method is invoked as a result of a form submission from my 'new' method in the new.html.erb:

<h1>New album</h1>

<% form_for(@album) do |f| %>

  <p>
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </p>
  <p>
    <%= f.label :description %><br />
    <%= f.text_field :description %>
  </p>
  <p>
    <%= f.label :genre %><br />
    <%= f.text_field :genre %>
  </p>
  <p>
    <%= f.label :country %><br />
    <%= f.text_field :country %>
  </p>
  <p>
    <%= f.submit 'Create' %>
  </p>
<% end %>

<%= link_to 'Back', albums_path %>
+2  A: 

Does Datamapper support a to_param method or have you implemented one on your Album model? Until we have Rails 3 and an "ActiveORM" layer to cover up the differences between ORMs, you have to make sure your code conforms to an AR-like API.

If there is a to_param method and this still doesn't work, try doing it the old fashioned way:

format.html { redirect_to(album_path(@album.id)) }

Clunkier but most likely effective.

austinfromboston
Wow. That worked. But why did it work? In my example, what is the "%23<Album:0x72d452c>"? Isn't that some kind of raw representation of the Album object? So, by creating the to_param method, how does that ensure that the id of the object is represented instead of the object representation? Is it because there is a default to_param method that represents the object as this code: "%23<Album:0x72d452c>"? Amazing. I'd love to know how you figured this out. You must really understand the innards of Rails pretty well.
Baker
The innards must do a respond_to? check before calling to_param, since the route methods also accept integers, arrays, and hashes.%23<Album:0x72d452c> is a url encoding of #<Album:0x72d452c>, which is more or less how Ruby exposes objects via the inspect method, unless those objects, like ActiveRecord, have overridden that method. Since your DM model is not an AR or an array or a hash, you just get to_s called on the object, probably as part of a string interpolation.I've had the opportunity to screw up which object I was sending to a route method, so I've seen this issue before.
austinfromboston
Thanks for explaining.
Baker