dm-is-select

A DataMapper plugin that makes getting the <select> options from a Model easier.

Installation

#  Add GitHub to your RubyGems sources 
$  gem sources -a http://gems.github.com

$  (sudo)? gem install kematzy-dm-is-select

Dependencies

The plugin depends upon the following:

  • dm-core ( >= 0.10.0)

  • dm-more ( >= 0.10.0) [not really, but your code will depend upon it]

NB! The plugin has been developed for and on DM’s next branch, so may NOT work on previous incarnations.

Getting Started

Let’s say you got a basic Category Model.

class Category
  include DataMapper::Resource
  property :id, Serial
  property :name, String

  is :select, :name

end

Through that simple declaration you get the following class method ..

Category.items_for_select_menu

…which returns an Array with the Model items in a structured way, ready for use.

[
  ["Select Category", nil], 
  ["  ------  ", "nil"], 
  ["Category 1", 1], 
  ["Category 2", 2], 
  ["Category 3", 3], 
  ["Category 4", 4], 
  ["Category 5", 5]
]

Great, but you don’t want the prompt to say “Select Category”, but

Category.items_for_select_menu( :prompt => "Choose Whatever" )

…which returns the Array with the prompt changed

[
  ["Choose Whatever", nil], 
  ["  ------  ", "nil"], 
  ["Category 1", 1], 
  ...<snip>...
]

OK, but you don’t like the divider node (2nd in output above). That’s fine, you remove it like this:

Category.items_for_select_menu( :divider => false )

…which returns the Array with the divider removed

[
  ["Select Category", nil], 
  ["Category 1", 1], 
  ...<snip>...
]

Hmm, fine, but I don’t want either a prompt or a divider, you say. That’s fine too.

Category.items_for_select_menu( :prompt => false )

…which returns the Array with the prompt and divider removed

[
  ["Category 1", 1], 
  ["Category 2", 1], 
  ...<snip>...
]

OK, that’s smooth, but my Category model is a tree with parents, children and so on. This won’t work with that.

Sure, no problem, just do this when you declare the Model:

is :select, :name, :is_tree => true

Then you can just use this

Category.items_for_select_menu( :prompt => "Choose Parent" )

…and you get this nicely formatted <select> options array

[
  ["Choose Parent", nil], 
  ["  ------  ", "nil"], 
  ["Top Level Category", 0],
  ["  ------  ", "nil"], 
  ["Parent-1", 1], 
  ["-- Parent-1-Child", 2], 
  ["-- -- Parent-1-Child-GrandChild", 3],
  ["Parent-2", 4], 
  ["-- Parent-2-Child", 5], 
  ["-- -- Parent-2-Child-GrandChild", 6]
]

NB! It only supports 3 levels at this point in time, as I think that’s enough in most use cases, but IF not, fix the code and let me know and I’ll add it.

Cool, but that “Top Level Category” node is a bit ugly, but easily fixed.

Category.items_for_select_menu( :root_text => "1st Parent (root)" )

…gives you:

[
  ...<snip>...
  ["  ------  ", "nil"], 
  ["1st Parent (root)", 0],
  ["  ------  ", "nil"], 
  ...<snip>...
]

You can even remove it all together by doing this:

Category.items_for_select_menu( :show_root => false )

Obviously all the config options from above works with Tree models as well.

Last Few Words

OK, I admit it, not the most impressive DM plugin there is, but hey, it sure helps keeping your model/views cleaner.

RTFM

For a better understanding of this gem/plugin, make sure you study the ‘dm-is-select/spec/integration/select_spec.rb’ file.

Errors / Bugs

If something is not behaving intuitively, it is a bug, and should be reported. Report it here: github.com/kematzy/dm-is-select/issues

Credits

Copyright © 2009-07-12 Kematzy [ kematzy gmail com ]

Licence

Released under the MIT license.