views:

151

answers:

1

Lets say you have an Invoice resource, and each Invoice has nested InvoiceLine resources, i.e. a very common nested resource pattern.

Now, where should one put the view for showing each individual invoice line as a row within the invoice? Should invoice lines be rendered as a partial under invoices/_line.html.erb, or should they get their own full-fledged view under invoices_lines/show.html.erb? Normally the former would be the obvious choice, but when you add AJAX functionality (for adding and editing lines in the invoice show view), things get complicated.

I find myself really struggling with this on a regular basis, and I'm not really sure of the right way to deal with it.

Here's what I'm thinking:

A RESTful route for this will likely look something like this:

map.resoures :invoices do |invoice|
  invoice.resources :lines, :controller => :invoice_lines
end

The standard folder structure for the views is:

app/
  views/
    invoices/
    invoice_lines/

Now, when rendering the entire invoice with all of its lines, my inclination would be to make each line into a _line.html.erb partial under invoices/. But then when I want to add some AJAX functionality for adding and editing lines, the PUTs and POSTs are routed to the invoice lines controller, so shouldn't the line rows be rendered by a standard show.html.erb view under invoice_lines.erb?

So should my views look like this:

app/
  views/
    invoices/
      index.html.erb
      show.html.erb
      _line.html.erb
    invoice_lines/

Or like this:

app/
  views/
    invoices/
      index.html.erb
      show.html.erb
    invoice_lines/
      index.html.erb
      show.html.erb

I'm stuck between having the InvoiceLinesController render its response to AJAX requests using the partial in invoices/_line.html.erb, or I can put the line row template code in invoice_lines/show.html.erb, and have invoices/show.html.erb render the individual lines as a component or AJAX request to InvoiceLinesController#index.

Neither alternative feels right. Any suggestions on the best practice here?

It feels as if invoice lines controller should have it's own set of views when rendered in the context of the invoice, but Rails doesn't really have an obvious provision for "contextualized" views.

+2  A: 

What about to put a partial _line.html.erb into the invoice_lines folder and then use this partial in the invoices_lines/show.html.erb template and the invoices/show.html.erb.

That's how I did it in similar situations.

  • This way all invoice specific view code is in the invoice folder and all invoice_line code is in the invoice_line folder.
  • You are DRY: you can use Ajax calls to the invoice_line controller or render the whole thing by displaying invoice/show.html.erb. invoice_items would be rendered both times through the same partial in invoice_lines/_line.html.erb

I hope this makes sense and is sort of an answer to your question. I'm not yet too experienced with Rails so I can't tell if this is "best practice"

StefanS
This is also what I would do.
Jimmy Cuadra