Forum: Ruby on Rails RESTful design/url question

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
D332266881d9f0c69f9277a483226739?d=identicon&s=25 Meech (Guest)
on 2007-02-14 15:26
(Received via mailing list)
New to rails and restful design, forgive me if this has been asked...

Lets say you have customers and orders models.    orders belongs_to
customers.


When viewing a customer, (/customers/1/)  I want to present the option
to view the customers orders (and eventually invoices, POs, etc).
What route would be within restful guidelines?

/customers/1:orders
/customers/1?view=orders
/customers/1/orders/
/orders:filter?customer=1

I think I would prefer each "page" of a customer detail have it's own
controller method -- this will allow me to keep the security decisions
completely within the controller easily.

Thanks
8217faf2bfdfa7daf10135d41ddd421e?d=identicon&s=25 Jeff Cohen (jeff)
on 2007-02-14 15:44
(Received via mailing list)
On Feb 14, 8:25 am, "Meech" <Meech...@gmail.com> wrote:
> New to rails and restful design, forgive me if this has been asked...

Not at all.

> /orders:filter?customer=1
I believe it would be /customers/1/orders/ .  You achieve this by
specifying that orders are nested within customers in your routes.rb:

map. resources :customers do |customer|
  customer.resources :orders
end

and then, in your OrdersController class, use a before_filter to
identify the customer, something like:

before_filter :get_customer

def get_customer
  @customer = Customer.find(params[:customer_id])
end

The customer_id key is automatically created for you when you nest the
routes.

> I think I would prefer each "page" of a customer detail have it's own
> controller method -- this will allow me to keep the security decisions
> completely within the controller easily.

That's how Rails works anyway - each "page" is an "action".  An action
is a coupling of a controller method and a template (.rhtml page).  So
you're on the right track.

Hope this helps
Jeff
softiesonrails.com
D332266881d9f0c69f9277a483226739?d=identicon&s=25 Meech (Guest)
on 2007-02-14 16:18
(Received via mailing list)
Thanks a bunch.

Follow-up question if you don't mind...

You are on the page to view a customers orders:
/customers/1/orders/

User clicks edit,   Would you replicate the edit, ala:

/customers/1/orders/1;edit

Or kick 'em to the orders resource?

/orders/1;edit

I'd like to be able to click "New Order" from within the customer view,
something like

/customers/1/orders/new

But the replication doesn't feel very DRY.
15c80c9bf8be5ba6e5eeac9cb0304464?d=identicon&s=25 Ed Hickey (Guest)
on 2007-02-14 16:25
(Received via mailing list)
you can use the builtin helper:

edit_order_path(@customer,@order)

that will create a link like "/customers/1/order/1;edit"

new_order_path(@customer) will create a link to "/customer/1/order/new"

ed
D332266881d9f0c69f9277a483226739?d=identicon&s=25 Meech (Guest)
on 2007-02-14 17:29
(Received via mailing list)
I understand that,

But in my instance orders is not only a child of customers, it's a
bonafide
resource of it's own, accessible via:

/orders/
/orders/1/
/orders/1;edit

So, if we are viewing a customer/orders page,  /customers/1/orders/  and
they click on "Edit Order".  Do we goto:

/customers/1/orders/1;edit    #edit order #1
Or
/orders/1;edit        #edit order #1

Do we implement both methods for the same function?

Syntactically, I think I like the both approach.   If a user clicks on
"Edit
Order" from within a customer orders details view, its pretty apparent
where
they should return after completing the edit.







________________________________

From: rubyonrails-talk@googlegroups.com
[mailto:rubyonrails-talk@googlegroups.com] On Behalf Of Ed Hickey
Sent: Wednesday, February 14, 2007 10:24 AM
To: rubyonrails-talk@googlegroups.com
Subject: [Rails] Re: RESTful design/url question


you can use the builtin helper:

edit_order_path(@customer,@order)

that will create a link like "/customers/1/order/1;edit"

new_order_path(@customer) will create a link to "/customer/1/order/new"

ed



On 2/14/07, Meech <meechman@gmail.com> wrote:


  Thanks a bunch.

  Follow-up question if you don't mind...

  You are on the page to view a customers orders:
  /customers/1/orders/

  User clicks edit,   Would you replicate the edit, ala:

  /customers/1/orders/1;edit

  Or kick 'em to the orders resource?

  /orders/1;edit

  I'd like to be able to click "New Order" from within the customer
view,
  something like

  /customers/1/orders/new

  But the replication doesn't feel very DRY.





  -----Original Message-----
  From: rubyonrails-talk@googlegroups.com
  [mailto:rubyonrails-talk@googlegroups.com
<mailto:rubyonrails-talk@googlegroups.com> ] On Behalf Of Jeff
  Sent: Wednesday, February 14, 2007 9:43 AM
  To: Ruby on Rails: Talk
  Subject: [Rails] Re: RESTful design/url question



  On Feb 14, 8:25 am, "Meech" < Meech...@gmail.com
<mailto:Meech...@gmail.com> > wrote:
  > New to rails and restful design, forgive me if this has been
asked...

  Not at all.

  > Lets say you have customers and orders models.    orders
belongs_to
  > customers.
  >
  > When viewing a customer, (/customers/1/)  I want to present the
option
  > to view the customers orders (and eventually invoices, POs, etc).
  > What route would be within restful guidelines?
  >
  > /customers/1:orders
  > /customers/1?view=orders
  > /customers/1/orders/
  > /orders:filter?customer=1

  I believe it would be /customers/1/orders/ .  You achieve this by
specifying
  that orders are nested within customers in your routes.rb:

  map. resources :customers do |customer|
    customer.resources :orders
  end

  and then, in your OrdersController class, use a before_filter to
identify
  the customer, something like:

  before_filter :get_customer

  def get_customer
    @customer = Customer.find(params[:customer_id])
  end

  The customer_id key is automatically created for you when you nest
the
  routes.

  > I think I would prefer each "page" of a customer detail have it's
own
  > controller method -- this will allow me to keep the security
decisions
  > completely within the controller easily.

  That's how Rails works anyway - each "page" is an "action".  An
action is a
  coupling of a controller method and a template (.rhtml page).  So
you're on
  the right track.

  Hope this helps
  Jeff
  softiesonrails.com
C4dc94c893471878a105761a9207f29b?d=identicon&s=25 Zack Chandler (Guest)
on 2007-02-14 18:04
(Received via mailing list)
On 2/14/07, Meech <meechman@gmail.com> wrote:
> So, if we are viewing a customer/orders page,  /customers/1/orders/  and
> they should return after completing the edit.
Meech,

Why do you want to expose orders as a first level resource
(/orders/1)?  If an order is always associated with a customer then
the nested way (/customers/1/orders/1) makes more sense.

What is it you're trying to accomplish by exposing orders via two
resource paths?

--
Zack Chandler
http://depixelate.com
15c80c9bf8be5ba6e5eeac9cb0304464?d=identicon&s=25 Ed Hickey (Guest)
on 2007-02-14 18:22
(Received via mailing list)
It depends on your model associations.  If Order belongs_to Customer,
then I
would go the "/customers/1/orders/new" because you'll need to reference
to
the Customer to create the Order.
You can use nested routes to acheive this.  Jamis Buck recently posted
about
something related to your question:
http://weblog.jamisbuck.org/2007/2/5/nesting-resources

ed
D332266881d9f0c69f9277a483226739?d=identicon&s=25 Meech (Guest)
on 2007-02-14 18:29
(Received via mailing list)
It just seems nicer to be able to view open/active orders across
customers to perform order-related functions.  The user could goto:

/orders/?q=active

Click on the order and manipulate it, instead of remembering the
customer, clicking on the orders tab, then clicking on the order.

But lets take this another level deep.   Orders have invoices,
invoices has payments.

customer
--order
----invoice
------payment

A person in accounts receivable would like to see unpaid invoices (as
a whole, not specific to a customer) in order to perform collection
activities.   Or be able to see payments within a deposit instead of
by customer/invoice, etc, etc...

While somebody can view invoices via    /customer/1/invoice/1/   how
would they see all open invoices for the company?  via:   /invoices/


This is why I posed the original question.   Is it restfull to
duplicate functions like this?

Is it?
/customers/1/invoices
/invoices/customers/1/
/invoices/?customer=1
C4dc94c893471878a105761a9207f29b?d=identicon&s=25 Zack Chandler (Guest)
on 2007-02-14 23:28
(Received via mailing list)
On 2/14/07, Meech <MeechMan@gmail.com> wrote:
> invoices has payments.
>
> /invoices/?customer=1
I understand where you're coming from now.  I think you could do this
a few ways.  One is to just expose the additional route in routes.rb

map. resources :customers do |customer|
  customer.resources :orders
end
map.admin_orders '/orders', :controller => 'orders'

You can also make an admin controller for handling workflow types of
things like order approval (in non-REST fashion).  Or you can view
status changing of orders (aka pending, verified, charged, shipped,
etc) as an OrderStatus resource and expose this via a REST controller.

Good luck.

--
Zack Chandler
http://depixelate.com
This topic is locked and can not be replied to.