Select List to change type of STI class


#1

Hi:

I’m trying to create a drop-down list to change the type of a Single
Table Inheritance class. I tried this:

<%= select :user, :type, [ [‘Author’, ‘Author’],
[‘Editor’, ‘Editor’],
[‘Administrator’, ‘Administrator’] ]
%>

But I get this error:

wrong argument type String (expected Module)


#2

On 3/30/06, jacob smails removed_email_address@domain.invalid wrote:

But I get this error:

wrong argument type String (expected Module)

You can do something like this:
selected_type = params[:user][:type]
klass = selected_type.constantize
new_user = klass.new(params[:user])


#3

Wilson B. wrote:

On 3/30/06, jacob smails removed_email_address@domain.invalid wrote:

But I get this error:

wrong argument type String (expected Module)

You can do something like this:
selected_type = params[:user][:type]
klass = selected_type.constantize
new_user = klass.new(params[:user])

Actually, the part I was struggling with was how to create the drop-down
list. I ended up just creating the list by hand (i.e. not using the form
helper). Then, in the controller I reset the subclass and save like
this:

@user[:type] = params[:user][:type]
if @user.save
etc…

It seems to work fine, but I still don’t understand the error I was
getting using the “select” form helper. Any ideas?


#4

On 3/31/06, jacob smails removed_email_address@domain.invalid wrote:

new_user = klass.new(params[:user])
It seems to work fine, but I still don’t understand the error I was
getting using the “select” form helper. Any ideas?

Oh, I see. You could do it this way:
@available_user_types = %w(Administrator User SuperCoolHacker)
@type_options = @available_user_types.zip(@available_user_types)

…and then in your view, use the @type_options variable as the
parameter to the “select” helper.

Here’s some code from the admin interface of an app I’m working on,
just in case it helps.
It needs to be simplified, but it might be a useful starting point.
Can you tell I’m paranoid about form parameters?

def new_item
if params[:item]
item_type = params[:item][:item_type]
item_type = ‘Item’ if item_type.blank?
else
item_type = ‘Item’
end
@item = item_type.constantize.new(params[:item])
@item.community = @community

if request.post? and @item.save
  flash[:notice] = "#{@item.item_type.titleize} was successfully 

created."
redirect_to :action => ‘show_item’, :id => @item
end
end

…and in the rhtml template, this:
<%= select ‘item’, ‘item_type’, Item::ITEM_OPTIONS,
{:prompt => “Select one:”}, :onchange => ‘item_type_select();’ %>

ITEM_OPTIONS is a constant in the superclass containing a
select-helper-compatible list of subclasses that users can choose
from.


#5

I would say just drop the first option for your array. I think the
select only takes one option as a string… ie [‘Author’, ‘Editor’,
‘Administrator’] or if you want something different…not in your case
though [[‘Author’, 1], [‘Editor’, 2], [‘Administrator’, 3]] Rails uses
the first item in the array as the list option and the second as the
value, if you want them to be different. Else, just use a single value.