views:

84

answers:

2

By 'view' here I mean different combinations of properties of the model, not the view of the traditional MVC. For example, I have the following model:

class Game < ActiveRecord::Base
  has_many :players
  belongs_to :status
  has_one :deck
  has_many :turns
  has_one :current_turn, :class_name => 'Turn', :conditions => ['turn_num = ?', '#{self.turn_num}']
end

I've written a full_xml method for Game that I use for the 'normal' get operation, so that I can include certain properties of players and current_turn, and then I don't have to do GETs on every player all the time. I also don't want to include ALL the properties and children and children's properties of the Game model on every GET

Now, however, I want to GET a game history, which is all the turns (and their properties/children). Initially I thought of a new model w/out a corresponding table, and then realized that wasn't necessary because the data and relationships are already there in the game and turns models. I also thought about writing a new action, but I thought I read somewhere that in the RESTful world, you shouldn't be writing any actions other than the core 7.

BTW, I'm thinking here of returning xml, because I'm using a Flex front end instead of rails views.

A: 

You have a couple of options here - I would use "nested resources" so you end up with a /game/:game_id/turns route which calls 'index' on the Turns controller. The other option is to create a GameHistory controller, which might be useful if there is additional logic associated with your game history.

There is not a one-to-one correspondence between controllers and models; there is however a one-to-one correspondence between controllers and RESOURCES. A game history is a whole different resource from a Game, just like a user session resource is different from an actual user resource (this is commonly used to allow for RESTful logins as well as RESTful user management) Hopefully this helps :)

Marcel Guzman
Nested URIs have nothing to do with REST.
Wahnfrieden
A: 

Yes, nested resources was the answer. This Railscast explains it nicely. I had briefly tried nested resources before, and couldn't get it to work. It was returning all the child resources, not only the nested resource of the parent resource. This was because I assumed Rails was automagically doing that for me, which it doesn't. The Railscast explains that you still have to make changes to the controller of the child resources, like so:

class TurnsController < ApplicationController
  # GET /turns
  # GET /turns.xml
  def index
    @game = Game.find(params[:game_id])
    @turns = @game.turns

    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @turns.to_xml( :except => [:created_at, :updated_at] ) }
    end
  end
  ... more methods
end

You also have to edit your routes.rb file. In this case, I want nested routes for both players and turns of the game, so I did this:

map.resources :games do |game|
    game.resources :players
    game.resources :turns
end