Как переопределить attr_protected?
-
22-09-2019 - |
Вопрос
У меня есть реализация 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.Ваше решение, хотя оно и работает, имеет недостаток в том, что позволяет проводить атаки.