2010-03-26 108 views
2

我有STI執行如下命令:如何覆蓋attr_protected?

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 

我創建了一個用戶的汽車的列表。對於每輛汽車,用戶界面設置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字段。

我希望有比這更好的方法。

回答

1

我落得這樣做:

class Automobile < ActiveRecord::Base 
private 
    def attributes_protected_by_default 
    super - [self.class.inheritance_column] 
    end 
end 
+0

我試過這個,但顯然Automobile.new(params [:汽車])不起作用,在我的創建控制器行動。 – 2011-05-18 15:00:12

0

我會在用戶添加一個輔助方法來實例化相應的子類:

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 

上面的代碼是「安全」的:攻擊者無法將任意文本注入汽車類型列。您的解決方案雖然有效,但具有啓用攻擊的缺點。

+0

我的情況是有點複雜。我在提交中有三層嵌套。我必須重新創建整個結構才能執行此驗證。我採取了爲汽車類中的'type'字段添加格式驗證。 – 2010-03-27 14:25:20