#80
Nov 18, 2007

Simplify Views with Rails 2.0

Rails 2.0 is almost here. One of the many features in this release is the smarter helper methods which can make your views much cleaner. Learn all about it in this Episode.
Download (9.3 MB, 6:03)
alternative download for iPod & Apple TV (7.6 MB, 6:03)

Resources

<!-- index.html.erb -->
<%= render :partial => @products %>

<!-- show.html.erb -->
<%= render :partial => @product %>

<!-- _product.html.erb -->
<% div_for product do %>
  <h2><%= link_to h(product.name), product %></h2>
  ...
<% end %>

<!-- new.html.erb and edit.html.erb -->
<% form_for @product do |f| %>
  ...
<% end %>

RSS Feed for Episode Comments 41 comments

1. Jamal Nov 19, 2007 at 03:20

When I type

<!-- index.html.erb -->
<%= render :partial => @products %>

Then it search for partial in the wrong folder?

/products/_product

and not

/product/_product


2. Joel AZEMAR Nov 19, 2007 at 03:43

If you use the namespace route like that :

map.namespace :admin do |admin|
    admin.resources :products
end

you can write this :

<% form_for([:admin,@product]) do |f| %>


3. Stephen Nov 19, 2007 at 04:39

Joel, I don't think the problem is a namespace. Jamal probably made a ProductController instead of a ProductsController.

Jamal, always remember to pluralize your RESTful controllers:

script/generate controller products


4. Jose Nov 19, 2007 at 08:37

Seem I am out of date here...So no more rhtml? .html.erb now?


5. Trent Nov 19, 2007 at 09:03

Yet another set of conventions that will help simplify Rails apps. I love it. I know a lot of people were disappointed that Rails 2.0 wasn't going to add any "big" features, but it's good to see that the focus has been on further simplifying the code that's written for the most common cases.


6. Andy Nov 19, 2007 at 09:16

Thanks for the video, I like this one.

But I have a question. This with REST is very confusing. If I have created a controller for example "ruby script/generate controller products/toys". How do I write in route.rb? I can't write "map.resources :products/toys".


7. pat Nov 19, 2007 at 10:22

please give us more info on rails 2.0. i just can't wait for the final RC.


8. Mathijs Nov 19, 2007 at 10:44

One thing that annoys me about the rails 2 view shortcuts is when using restful nested controllers.
Maybe I'm just doing something wrong.

routes.rb:
map.resources :people,
  :has_many => :written_articles

now, in views for my WrittenArticlesController, I can't use form_for @article anymore.
Neither can I use link_to 'Show', @article anymore.

I have to revert to person_written_messages_path(@person, @article) which is silly.

This isn't the worst,
It is far worse that form_for @article won't work anymore (which is very nice to have, because new and edit can use the same form) and I have to revert to full paths again, and _manually_ tell the form to use PUT or POST.

Am I doing something wrong here? Wouldn't it be much cleaner for rails to just assume (since it's rendering a view for the written_articles controller) I'm talking about the @article in scope of the person who wrote it? And then if I really want to link to the message itself force me to use article_path(@article) ?


9. Rupak Ganguly Nov 19, 2007 at 12:44

Since mew.html.erb and edit.html.erb share the same code except the Title maybe, can we replace the foll. code with a partial like <%= render :partial => "form" %>?

<!-- new.html.erb and edit.html.erb -->
<% form_for @product do |f| %>
  ...
<% end %>

Will the system be smart enough to detect if it is the case of new or edit from within the partial?


10. Jose Nov 19, 2007 at 20:18

Ok...I feel stupid, can someone give me links or explain a little bit of ERB?


11. Jose Nov 19, 2007 at 20:18

Please! :)


12. Jose Nov 19, 2007 at 20:21

I mean, why the use of the filename ".html.erb"?

PS: sorry for the many posts, this keyboard doesn't behave well...


13. QuBiT Nov 19, 2007 at 23:27

@Jose .. just rename your rhtml files to html.erb, and your rxml to xml.builder and everything will work well or just use this code:

[code]
  task :rhtml2erb do
    desc 'Renames all your rhtml views to erb'
    Dir.glob('app/views/**/*.rhtml').each do |file|
      puts `svn mv #{file} #{file.gsub(/\.rhtml$/, '.html.erb')}`
    end
  end
[/code]

Everyone who want to use the latest version of rails has just to use this in his application root folder:

[code]
"svn co http://dev.rubyonrails.org/svn/rails/trunk vendor/rails"
[/code]

it will checkout the latest version from trunk and puts it into vendor/rails ... rails will check if it is available automatically before it uses the installed version.

one remark -> (the version aufter 8165 seems to have one bug and does not work correct today, but maybe they correct it until tomorrow)
so append "--revision 8165" to the upper command.


14. Ryan Bates Nov 20, 2007 at 10:14

@Mathijs, try this:

form_for [@person, @article]

I normally don't use nested resources so I'm not certain this will work.

@Andy, the map.resources method supports a :path_prefix option. Try using that:

map.resources :toys, :path_prefix => 'products'

Untested.

@Rupak, yep, form_for works great when placed in a partial. That's what I usually do.


15. windhood Nov 20, 2007 at 16:46

any plan for using jquery instead of prototype?


16. Jose Nov 21, 2007 at 00:14

Hey, thanks a lot QuBiT, very helpful.

Ryan, great work as usual!


17. nicolash Nov 21, 2007 at 07:25

@Mathijs
...#6432 from the changelog
url_for([parent, child])
generates /parents/1/children/2 for the nested resource.
Likewise with the other simply helpful
methods like
form_for
and
link_to.


18. nicolash Nov 21, 2007 at 07:32

@Jose
in addition to what QuBit said:
xyz.js.erb for Javascript-generating files in the views
xyz.erb for mail-generating files in the views


19. Chris W Nov 23, 2007 at 16:18

If you are looking for jQuery for Rails, check this out. http://ennerchi.com/projects/jrails


20. Henry Nov 24, 2007 at 12:29

Hey Ryan. Thou art the man. Rock on.


21. Tim Nov 25, 2007 at 07:43

Nice screencast, good work!


22. Anthony Ettinger Nov 29, 2007 at 07:29

Nice work. I like the simplified div_for, and partials as well.

I'm a little confused on puts vs. post/get


23. sandro d. Dec 03, 2007 at 17:59

I'm a little confused. If you use

<!-- index.html.erb -->
<%= render :partial => @products %>

<!-- show.html.erb -->
<%= render :partial => @product %>

does it means the the _product.html.erb partial contains the fields of the forms (edit/new) and also the lines of your list (index).

What am I missing here?


24. Ryan Bates Dec 06, 2007 at 08:13

@sandro, the "_product.html.erb" partial only contains the html to display the product - not any form/fields to edit a product. I did not put form fields in a partial for simplicity sake, but you would likely want to create some kind of "_form.html.erb" partial for that.


25. Dave Klawitter Dec 17, 2007 at 13:40

When I do this I get a 'undefined method "article_path"' error from my partial. It doesn't like "article" in my link_to.


26. div Dec 19, 2007 at 04:38

Would you pl help me to fix this,in my old rails version i used to render files like

render(:partial=>'list_categories')

Now its not working with version 2.0.2.How can i make it work???
Thanks in advance


27. saurabh purnaye Jan 04, 2008 at 01:40

really needed to work with the new concepts in rails 2.0.2


28. Lili Jan 17, 2008 at 01:17

I want to some test about Rails2.0,I hope get your help and understand


29. Anthony Underwood Jan 17, 2008 at 05:57

Great cast as always.
1) PLease can you tell me where the best place to find documentation on this feature is (rails api)
2) I'm not quite sure how this would work since it's likely that the partial for an index will need to be different for a partial from the show. The index view is likely to be much briefer than show view.

Thanks for any tips

Anthony


30. Anton Jan 22, 2008 at 08:39

I'd like to ask sandro.d#s question agian in a slightly different form

I'd like the 'view' and 'edit'/'new' to look the same. Same layout and laels & screen position. So I'd like to use the same ... well, its not really a _form now is it? Or is it? And how would you address it in 'view.rhtml.erb'?


31. Wesley Jan 24, 2008 at 02:07

Just a quick question. When you use the shortcut for displaying partials:

render :partial => @products

does it make any assumptions about where the partial is stored? I have a feeling it assumes the partial is stored in the controller with the same name.

To illustrate, imagine a directory like such:

views/products/_product.html.erb
views/users/_product.html.erb

When rendering by doing:

render :partial => @product

the shortcut automatically gets the partial from views/products, even though the render may be in the users controller.

However, this problem does not occur when doing it the long way:

render :partial => 'product', :object => @product

Any comments?


32. supaspoida Feb 15, 2008 at 19:27

Ryan,

I have been using this style of rendering partials since I first watched this screencast, and I really appreciate the abbreviated syntax and the conventions that it encourages. However, I seem to be having some issues passing locals to partials with this method, as in I can't seem to do it at all. I have asked the railsforum, but haven't had any luck and was hoping you might chime in. Thanks! The post is here:

http://railsforum.com/viewtopic.php?id=15301


33. supaspoida Feb 18, 2008 at 22:10

As a followup to my previous post, my issue appears to have been a bug, and has been resolved in changeset 8822.

http://dev.rubyonrails.org/changeset/8822


34. Rome Mar 02, 2008 at 13:37

How would I use a path prefix to my restful routes?

ex.

Instead of "http://mysite.com/articles/1...
Have "http://mysite.com/blog/articles/1...

Do i make a separate controller?
script/generate controller Blog::Articles ?

Or is it something simple that I'm completely overlooking?


35. Ryan Bates Mar 03, 2008 at 19:55

@Rome, there is a :path_prefix option for map.resources which should do the job:

map.resources :articles, :path_prefix => '/blog'

@Wesley, yes, the partial is assumed to be in the controller with the same name (no matter what controller you're currently in). Usually this is an acceptable assumption, but if you don't want this behavior it's best to define the location manually.

@Anton, if you want the show, edit, and new actions to use all the same view you can create just one (show.html.erb) and define that in the other actions:

def new
  #...
  render :action => 'show'
end

If there are minor differences then I recommend you stick with a partial.


36. Kotosha Mar 09, 2008 at 00:53

Yeah, rails is making shorter and shorter. That's nice but I am wondering when we approach the border when one command will do everything:D.
Great cast as usually.


37. byrnejb Mar 14, 2008 at 12:46

I extracted the following from a new.html.erb template:

<h3> Entity Header </h3>
<% fields_for(@entity) do |e| %>
  <fieldset>
    <p>
      <b>Entity Name</b><br />
      <%= e.text_field :entity_name %>
    </p>

    <p>
      <b>Entity Legal Name</b><br />
      <%= e.text_field :entity_legal_name %>
    </p>

    <p>
      <b>Entity Legal Form</b><br />
      <%= e.text_field :entity_legal_form %>
    </p>
  </fieldset>

<% end %>

and put this in its place:

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

  <% render :partial => "entities/entity_fields_for", :object => @entity %>

When i try and add a new client the log shows this:

  Parameters: {"action"=>"new", "controller"=>"clients"}
Rendering template within layouts/clients
Rendering clients/new
Rendered entities/_entity_fields_for (0.00368)
Completed in 0.05866 (17 reqs/sec) | Rendering: 0.01921 (32%) | DB: 0.00000 (0%) | 200 OK [http://localhost/clients/new]

but nothing from the partial actually appears in the html that is generated. This is my very first attempt at using partials and I am at a loss. Is there anything obvious that I am doing wrong?


38. byrnejb Mar 14, 2008 at 12:52

I left off the = from the opening <% of the render call. Sigh.


39. dblanken Mar 31, 2008 at 11:41

When using a namespace, is there a path to load the partial. For instance, is there anything like:

form_for([:admin, @post]) do
  render :partial => [:admin, @post]
end

to tell the partial to look in /admin/post/_post.html.erb instead of /post/_post.html.erb?


40. kino May 23, 2008 at 01:08

Do you know if its possible to use http to request information from the user other than login credentials?


41. RailscastsRule Jun 27, 2008 at 15:59

@Jose - If your "keyboard doesn't behave well" wouldn't there be fewer posts from you?

Add your comment:

(SKIP THIS ONE)

(required)

(not shown)


(use pastie or gist for code)

sponsored by:
if you want to help:
required:
Get Quicktime Player