2

次のように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これにより、フィールドが保護リストから削除されます。

これよりも良い方法があることを願っています。

4

2 に答える 2

1

私はこれをやってしまった:

class Automobile < ActiveRecord::Base
private
  def attributes_protected_by_default
    super - [self.class.inheritance_column]
  end
end
于 2010-04-21T07:12:38.200 に答える
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列に任意のテキストを挿入することはできません。ソリューションは機能しますが、攻撃を可能にするという欠点があります。

于 2010-03-27T13:23:14.443 に答える