Notes posted by nachocab
RSS feed
:selected
If you want some object to be selected by default, be sure to use its id, not the whole object.
collection_select(:post, :author_id, Author.all, :id, :name_with_initial, {:selected => current_book.authors.map(&:id)}) #=> :selected => [1,2,3,4]
and not
collection_select(:post, :author_id, Author.all, :id, :name_with_initial, {:selected => current_book.authors})

link_to_remote renders javascript as text
If you want to render an RJS file with link to remote you shouldn’t specify the :update function. Using this:
link_to_remote('add',:update=> 'someId', :url => {:controller => 'my_controller', :action => 'new'} ) # assume having 'my_controller/new.rjs'
will return something like
try { Element.update("someElement\n"); } catch (e) { alert('RJS error:\n\n' + e.toString()); alert('Element.update(\"someId\", \"item\\n\");'); throw e }
You should be specifying the id you are updating in the RJS file, not in link_to_remote. This will render correctly:
link_to_remote('add',:url => {:controller => 'my_controller', :action => 'new'} ) # assume having 'my_controller/new.rjs'
Only use :update when rendering html.


Exceptions while debugging
If the error wasn’t stored in a variable, you can still see it by looking at the global variable $ERROR_INFO.


Use collect in nested content_tags
Remember to use #collect instead of #each in nested content_tags
arr = ['a','b','c'] content_tag :div do arr.collect { |letter| content_tag(:scan, letter) end #=> <div> # <scan>a</scan> # <scan>b</scan> # <scan>c</scan> # </div>
If you used #each you would get this (which is probably a mistake):
#=> <div> # abc # </div>

Routes = RouteSet.new
In config/routes.rb you can see this:
ActionController::Routing::Routes.draw do |map| #routes end
If you want to look at the code in ActionController::Routing you won’t find the definition of Routes. That’s because it’s actually an instance of the class RouteSet, defined in action_controller/routing.rb
Routes = RouteSet.new

How to test different responses of respond_to
You can shorten this:
@request.env['HTTP_ACCEPT'] = "application/rss"
To this:
@request.accept = "application/rss"
Also, if you send more than one Mime type, it will render the first one:
@request.accept = "text/javascript, text/html" #=> renders JS @request.accept = "text/html, text/javascript" #=> renders HTML

Array expansion in blocks
The syntax can be improved as changing the second parameter of the block (values) and using an array of two variables instead, which will be used by Ruby as the key and value of “array”.
array = [['A', 'a'], ['B', 'b'], ['C', 'c']] hash = array.inject({}) do |memo, (key, value)| memo[key] = value memo end hash # => {'A' => 'a', 'B' => 'b', 'C' => 'c'}

params hash gets the model id automatically
The params hash gets automatically populated with the id of every model that gets passed to form_for. If we were creating a song inside an existing album:
URL:/albums/209/songs/new form_for [@album, @song] do |f| ... f.submit "Add" end
The params hash would be:
params = {"commit"=>"Add", "authenticity_token"=>"...", "album_id"=>"209", "song"=>{"song_attributes"=>{...}} }
So, in the songs_controller you could use this album_id in a before_filter:
before_filter :find_album protected def find_album @album = Album.find(params[:album_id]) end
If you only did this:
form_for @song do |f|
You would get this params hash:
params = {"commit"=>"Add", "authenticity_token"=>"...", "song"=>{"song_attributes"=>{...}} }

The reverse operation of split is join.
Given that String#split returns an array, its reverse operation is Array#join. Example:
"life is awesome".split =>["life","is","awesome"] ["life","is","awesome"].join(" ") =>"life is awesome"