belongs_to user interface, take II
In UI for belongs_to relationships, I discussed a way to make a belongs_to UI. Unfortunately, it was very complex, and I found a better way since then.
I have to thank Michael C. Toren for the spark that inspired this entry.
The way I now do my belongs_to UIs today is much simpler. Let us assume the following models for discussion:
app/models/product.rb
1 class Product 2 belongs_to :color 3 4 validates_presence_of :color 5 end
app/models/color.rb
1 class Color 2 def self.all 3 self.find(:all, :order => 'name') 4 end 5 end
When creating a product, we would like to select the color of said product. The UI should be a simple SELECT box.
Rails makes it easy to have SELECT boxes coming from some table:
app/views/products/_form.rhtml
1 <p><label>Description: 2 <%= text_field 'product', 'description' %></p> 3 <p><label>Color: 4 <%= collection_select 'product', 'color_id', 5 Color.all, :id, :name %></p>
See how I call #collection_select with color_id instead of color ? That’s the trick to use.
One nice side-effect of this is that validation will still run. The validates_presence_of declaration will be respected if no color_id is assigned.
The only problem left to resolve is the field highlighting that Rails field helpers automagically add when a field validation rule is not respected.
There are two ways to resolve that:
- Change the validation to require both
colorandcolor_id(adding two messages to the message area), or; - Add the error
DIVmanually when an error is found on the counterpart field, such as this:
app/views/products/_form.rhtml
1 <p><label>Description:
2 <%= text_field ‘product’, ‘description’ ></p>
3 <p><label>Color:
4 <div class="<= ‘fieldWithErrors’ if error_message_on ‘product’, ‘color’ >">
5 <= collection_select ‘product’, ‘color_id’,
6 Color.all, :id, :name %></div></p>
UPDATE (2006-01-04): John Indra noted that there didn’t exist an
error_messages_on, onlyerror_message_on. Code above corrected.blog comments powered by DisqusSearch
Your Host
I am François Beausoleil, a Ruby on Rails and Scala developer. During the day, I work on Seevibes, a platform to measure social interactions related to TV shows. At night, I am interested many things. Read my biography.
Top Tags
Books I read and recommend
Links
Projects I work on
Projects I worked on