I\'m new to rails and I\'m kind of stuck with this design problem, that might be easy to solve, but I don\'t get anywhere: I have two different kinds of advertisements: high
[Rewritten with simpler solution that works fully:]
Iterating on the other answers, I have come up with the following solution for a single controller with Single Table Inheritance that works well with Strong Parameters in Rails 4.1. Just including :type as a permitted parameter caused an ActiveRecord::SubclassNotFound error if an invalid type is entered. Moreover, type is not updated because the SQL query explicitly looks for the old type. Instead, :type needs to be updated separately with update_column if it is different than what is current set and is a valid type. Note also that I've succeeded in DRYing up all lists of types.
# app/models/company.rb
class Company < ActiveRecord::Base
COMPANY_TYPES = %w[Publisher Buyer Printer Agent]
validates :type, inclusion: { in: COMPANY_TYPES,
:message => "must be one of: #{COMPANY_TYPES.join(', ')}" }
end
Company::COMPANY_TYPES.each do |company_type|
string_to_eval = <<-heredoc
class #{company_type} < Company
def self.model_name # http://stackoverflow.com/a/12762230/1935918
Company.model_name
end
end
heredoc
eval(string_to_eval, TOPLEVEL_BINDING)
end
And in the controller:
# app/controllers/companies_controller.rb
def update
@company = Company.find(params[:id])
# This separate step is required to change Single Table Inheritance types
new_type = params[:company][:type]
if new_type != @company.type && Company::COMPANY_TYPES.include?(new_type)
@company.update_column :type, new_type
end
@company.update(company_params)
respond_with(@company)
end
And routes:
# config/routes.rb
Rails.application.routes.draw do
resources :companies
Company::COMPANY_TYPES.each do |company_type|
resources company_type.underscore.to_sym, type: company_type, controller: 'companies', path: 'companies'
end
root 'companies#index'
Finally, I recommend using the responders gem and setting scaffolding to use a responders_controller, which is compatible with STI. Config for scaffolding is:
# config/application.rb
config.generators do |g|
g.scaffold_controller "responders_controller"
end