代码之家  ›  专栏  ›  技术社区  ›  Harish Shetty

如何覆盖受保护的属性?

  •  2
  • Harish Shetty  · 技术社区  · 15 年前

    我的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 字段和与汽车关联的属性 类型 字段被忽略,因为它是受保护的属性。

    如何解决这个问题?有没有一种声明性的方式 unprotect 受保护的属性?

    编辑: 这是我目前针对这个问题的解决方案: attributes_protected_by_default 我的模型类中的私有方法。

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

    这将删除 字段。

    我希望有比这更好的办法。

    2 回复  |  直到 15 年前
        1
  •  1
  •   Harish Shetty    15 年前

    最后我做了这个:

    class Automobile < ActiveRecord::Base
    private
      def attributes_protected_by_default
        super - [self.class.inheritance_column]
      end
    end
    
        2
  •  0
  •   François Beausoleil    15 年前

    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列注入任意文本。您的解决方案虽然有效,但缺点是启用攻击。