0

I have just started out learning rails and ruby, so please bear with me if this is too dumb.

There are several different AppModule types in my app, which have different behavior but similar data, so I save them using single table inheritance.

However when trying allow the user to explicitly select which type they want in app_modules/new.html.erb I get the warning WARNING: Can't mass-assign these protected attributes: type. Here is the relevant code:

<% form_for(@app_module) do |f| %>
  <%= f.error_messages %>

  <p>
    <%= f.label :type %><br />
    <%= f.select( :type, options_from_collection_for_select(AppModule.subclasses().map{ |c| c.name}, 'to_s', 'to_s')) %>
    </p>

  <%= f.submit 'Create' %>
 <% end %>

I have tried explicity setting attr_accessible :type in the model file but it didn't work

I am using rails 2.3.8 and ruby 1.8.7.

Any help greatly appreciated, thanks...

Engin Kurutepe
  • 6,719
  • 3
  • 34
  • 64

3 Answers3

6

You shouldn't ever have to set the type attribute manually. Use the subclasses you created instead.

model = params[:app_module].delete(:type).constantize
model = AppModule unless model.is_a?(AppModule)
@app_module = model.new(params[:app_module])
Adam Lassek
  • 35,156
  • 14
  • 91
  • 107
  • This is really convenient with STI. – Mark Thomas Nov 16 '10 at 23:50
  • Of course you'd add a check to ensure only types you specifically allow can be created in this fashion. That code would allow a user to create any class they like within your app and provide it with whatever initialisation parameters they want (if I'm not mistaken). – Brendon Muir Nov 13 '15 at 21:52
  • @BrendonMuir Yes that's a good point, you should always sanitize params that execute code like this. I'll add a line for that. – Adam Lassek Nov 13 '15 at 23:10
  • 1
    Thanks @Adam. I know this question is for Rails 2 but in Rails 4 they added the ability to specify :type in the attributes and it does a check that :type is a valid subclass of the superclass: https://github.com/rails/rails/commit/89b5b31cc4f8407f648a2447665ef23f9024e8a5 – Brendon Muir Nov 13 '15 at 23:21
1

Add this to your base class:

  def attributes_protected_by_default
    super - [self.class.inheritance_column]
  end

I recommend Adam's method unless you are dealing with a mixed list.

Harish Shetty
  • 64,083
  • 21
  • 152
  • 198
0

I just need to comment following line in my 'config/application.rb' to solve this issue.

# config.active_record.whitelist_attributes = true
Dhanu Gurung
  • 8,480
  • 10
  • 47
  • 60