我的STI实施如下:
class Automobile < ActiveRecord::Base
end
class Car < Automobile
end
class Truck < Automobile
end
class User < ActiveRecord::Base
has_many :automobiles
accepts_nested_attributes_for :automobiles
end
我正在为用户创建汽车列表。对于每个汽车,UI设置type
字段以及与汽车相关联的属性。在表单提交时,type
字段将被忽略,因为它是受保护的属性。
如何解决此问题?是否有unprotect
受保护属性的声明方式?
修改
这是我目前解决问题的方法:
我覆盖模型类中的attributes_protected_by_default
私有方法。
class Automobile < ActiveRecord::Base
private
def attributes_protected_by_default
super - [self.class.inheritance_column]
end
end
这会从受保护列表中删除type
字段。
我希望有一种比这更好的方法。
答案 0 :(得分:1)
我最终这样做了:
class Automobile < ActiveRecord::Base
private
def attributes_protected_by_default
super - [self.class.inheritance_column]
end
end
答案 1 :(得分:0)
我会在User上添加一个帮助器方法来实例化相应的子类:
class User < ActiveRecord::Base
def self.automobile_from_type(type)
self.automobiles << case type
when "Car"
Car.new
when "Truck"
Truck.new
else
raise ArgumentError, "Unknown automobile type: #{type.inspect}"
end
end
end
像这样使用:
class AutomobilesController < ApplicationController
def create
@automobile = current_user.automobile_from_type(params[:automobile][:type])
if @automobile.update_attributes(params[:automobile]) then
redirect_to @automobile
else
render :action => :new
end
end
end
上面的代码是“安全的”:攻击者无法将任意文本注入您的automobiles.type列。您的解决方案虽然有效但却具有启用攻击的缺点。