Вопрос

У меня есть реализация 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

Я создаю список автомобилей для пользователя.Для каждого автомобиля пользовательский интерфейс устанавливает 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 поле из защищенного списка.

Я надеюсь, что есть способ получше, чем этот.

Это было полезно?

Решение

В итоге я сделал это:

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

Другие советы

Я бы добавил вспомогательный метод для 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.Ваше решение, хотя оно и работает, имеет недостаток в том, что позволяет проводить атаки.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top