Restful Nested Resource without ugly id

To all:

hi i am pretty noob. Basically I am learning via copy and paste, so
please forgive me.

I am using rails 1.2.6.

I built 2 scaffold_resource called traders and orders.

I want a localhost:3000/v1/traders/{trader_name}/orders

so I did a

base = ‘/v1’

map.resources :traders, :path_prefix => base

#trader_url
trader_url = base + ‘/traders/:login’

map.resources :orders, :path_prefix => trader_url

inside the orders_controller:

i did this
def index

@orders = Order.find_by_trader_id(@trader.id)
respond_to do |format|

   format.html
end

I have 2 questions:

  1. am i doing it right in the routes.rb?

  2. i get an error at the webpage.

undefined method `each’ for #Order:0x4624f18

Extracted source (around line #7):

4:


5:
6:
7: <% for order in @orders %>
8:
9:
10: <% for column in Order.content_columns %>

what is wrong?

Please help. I thank you all.

@orders = Order.find_by_trader_id(@trader.id)

this will find only one order, so there’s no ‘each’

otherwise your view code would be ok

@orders = Order.find_all_by_trader_id(@trader.id)

would do what you want

but it would be better (more rails like) to define
has_many :orders
in Trader Model and
belongs_to :trader
in Order model

then you could use

@trader.orders.each do |order|

in the view

Thank you.

However, is that a good idea about using the @trader.orders.each do |
order|
considering that it appears less MVC?

What about my routes.rb? Any room for improvement?

On Dec 7, 10:26 pm, Thorsten M. <rails-mailing-l…@andreas-

However, is that a good idea about using the @trader.orders.each do |
order|
considering that it appears less MVC?

just an example or option. after all it does, what you do anyway and it
keeps things easy readable
you could of course make use of partials and hand over @trader.orders as
an collection:
render :partial => ‘order_list’, :collection => @trader.orders

but if there’s a question between MVC and Rails, i go for rails :slight_smile:

What about my routes.rb? Any room for improvement?
seems ok to me, but i’m not that much an expert in the routing stuff

maybe nested routing would be an option:

map.resources :traders do |trader|
trader.resources :orders
end

would give you nice path helpers like:

trader_orders_path(trader_id)

to get the full path to the index of orders for a trader with
params[:trader_id] filled as you expect it

i googled around and i know abt the map.resources code block that you
showed me.

however, that would give me urls like /traders/2/orders/2

instead of traders/peter/orders/2

is there an alternative to the one that I wrote and still give me what
i want?

sure, just overwrite to_param in Trader model

def to_param
name
end

this would give eg ‘peter’ for trader_orders_path(@trader) or
trader_order_path(@trader, 2) for your example
would be better to have an url_name col for that, to make sure the name
can be used in an url (no spaces etc) or to return an encoded form of
name

then search your trader by the name, handed back in params[:trader_id]

In order to do what you want to do you will have to do two things:

1, override the to_param method on your models

Assuming you have a “name” field in your Trader model, in the
Trader.rbfile, you’d add this:

def to_param
self.name
end

That’ll make your URLs work as long as you’re always passing the @trader
object around. However, you have to change all of your finders now to
look
up by name

So, instead of

@trader = Trader.find(params[:id])

You must do
@trader = Trader.find_by_name(params[:id])

Repeat for the user model and controllers.

If you’re just starting out, don’t mess with this now. Learn how routing
and
finders actually work. You may discover a better way too. The ids
don’t
hurt anything and are much less volatile. If you change the trader’s
name
for example, the link is no longer valid.

Also, scaffolding isn’t meant for production. The URL stuff you’re
trying
to do is infinitely easier to do if you don’t use scaffolding. That’s
why I
say don’t tackle this now, wait until you understand how everything
works
together. Once you get it, these types of URLs become trivial because
you’re WRITING the finders yourself, instead of changing a bunch that
were
originally intended to work a different way.

Best of luck!

Learn how routing and
finders actually work.

I am currently learning by playing around with the scaffolds. Do you
have certain resources to point me to? Bear in mind, I am pretty damn
noob.

Also, scaffolding isn’t meant for production.

Oh no, I want to do one for a very simple game for production. If I
dont use scaffold, i may be lost. Even if i code from scratch, i will
inevitably copy teh code from scaffold.

I do have the eBook of Agile Devt with Rails and a few other Rails
eBook. But sometimes I feel the examples they use are a tad too
simple. Furthermore, i intend to use make a more Restful application.

Please help. THanks

map.resources :traders do |trader|
trader.resources :orders
end

would give you nice path helpers like:

trader_orders_path(trader_id)

i googled around and i know abt the map.resources code block that you
showed me.

however, that would give me urls like /traders/2/orders/2

instead of traders/peter/orders/2

is there an alternative to the one that I wrote and still give me what
i want?

thank you.