На днях скачал гем acts_as_taggable_on_steroids-1.2 и попытался его прикрутить к приложению.
На удивление, сразу не получилось, хотя я следовал простой инструкции по инсталляции и по применению.
Когда я сабмитил форму с новым объектом модели (помеченной acts_as_taggable) с тегами, получал ошибку ActiveRecord::RecordInvalid: "name не может быть пустым" (Name can't be blank) как будто на попытке вставить создать тег с незаполненным названием. Естественно в контроллере оно было заполнено, а пока дошло через стек ActiveRecord до сохранения куда-то подевалось.
Оказалось, что в этом виноват гем validates_captcha-0.9.3. Проблема в том, что validates_captcha дополняя своим модулем ActiveRecord::Base прописывает в attr_accessible для всех моделей свои атрибуты. И с момента когда attr_accessible становится не nil, начинаются траблы со всеми моделями приложения. Ведь до подключения гема validates_captcha mass assignment прекрасно работал, т.к. у моделей attr_accessible был равен nil.
в файле validates_captcha/rails/init.rb ActiveRecord:::Base расширяется модулем ValidatesCaptcha:
config.after_initialize do
::ActiveRecord::Base.send :include, ValidatesCaptcha::ModelValidation
а в файле validates_captcha/lib/validates_captcha/model_validation.rb устанавливается для всех моделей attr_accessible:
module ValidatesCaptcha module ModelValidation def self.included(base) #:nodoc: base.extend ClassMethods base.send :include, InstanceMethods base.class_eval do attr_accessible :captcha_challenge, :captcha_solution ... end end end
можно убедиться в этом так:
подключи этот гем через development.rb
config.gem "validates_captcha", :lib => 'validates_captcha', :source => 'http://gems.github.com', :version => '0.9.3'
запусти консоль
ruby script/console
выполни код
>class Model<ActiveRecord::Base;end; Model.attr_accessible => #<Set: {"captcha_solution", "captcha_challenge"}>
вот это и не нормально, что для всех моделей не важно вызван для них метод validates_captcah или нет устанавливаются общие attr_accesible.
Mass assignment используется, например, при создании объекта модели:
Tag.create(:name => name)
которое и перестает работать в приложении, где используется validates_captcha.
поправить просто - надо доопределить модель Tag:
class Tag
attr_accessible :name
end
Вероятно автор validates_captcha установил attr_accessible для всех моделей не случайно - это заставляет определять attr_accessible, иначе mass assignment перестает работать. Насколько это его решение полезно непонятно.
Илья Кислинский
как-то так