Rails не может массово назначать защищенные атрибуты для id, created_at

Я использую рельсы в качестве серверной части сайта backbone.js, поэтому я постоянно передаю объекты рельсов туда и обратно.

Я замечаю ошибки в рельсах, возвращающих WARNING: Can't mass-assign protected attributes: id, created_at, updated_at.

Конечно, я нахожу это странным, потому что мне никогда не приходилось включать эти поля. Мой json выглядит довольно нормально, насколько я могу судить.

 Parameters: {"id"=>1, "updated_at"=>"2011-04-21T16:41:02Z"},  "created_at"=>"2012-02-23T21:01:02Z", "action"=>"test update"}

person pedalpete    schedule 24.02.2012    source источник


Ответы (2)


В вашем JSON нет ничего плохого. Вопрос в безопасности. Rails по умолчанию защищает определенные атрибуты от создания или обновления из гигантского хэша. Именно на это указывает ошибка, когда используется термин «массовое назначение».

Опубликованный вами JSON:

Parameters: {"id"=>1, "updated_at"=>"2011-04-21T16:41:02Z"}, "created_at"=>"2012-02-23T21:01:02Z", "action"=>"test update"}

содержит поля id, created_at и updated_at. Когда этот JSON передается в действие, а хеш используется в model_object.update_attributes(hash_fields), вы получите эту ошибку. Чтобы избежать этой ошибки, вы можете удалить поля из хеша и назначить их позже, или, в идеале, позволить ActiveRecord работать за вас и просто игнорировать их.

Если вам действительно нужно их назначить, вы можете сделать это так:

 model_object.id = id_variable
 model_object.created_at = created_at_variable
 model_object.updated_at = updated_at_variable
 model_object.save

EDIT1 (чтобы ответить на комментарий о возврате идентификатора):

Если вы используете модель REST Rails и вызываете URL-адрес контроллера/:id/action, вам не нужно передавать идентификатор обратно, поскольку эта информация уже встроена в URL-адрес. Доступ к нему можно получить через params[:id], а к хешу — через params[:model_name] (в соответствии с моделью Rails).

Если вы делаете что-то другое и идентификатор должен быть в возвращаемом JSON, вы можете просто выполнить id = params[:model_name][:id].delete, и это удалит идентификатор из хэша и вернет значение за один вызов. Это не идеально, но может выполнить работу в крайнем случае.

person salt.racer    schedule 24.02.2012
comment
Но для обновления всегда требуется, чтобы идентификатор возвращался, но не обновлялся. Думаю, это было моей самой большой заботой. Если я не отправлю магистральные метки времени, они не будут возвращены, но мне нужно отправить идентификатор. Наверное, поэтому я так смущен. Я вижу, как рельсы «защищают меня», но я хотел бы знать, почему я вижу это только в этом случае. - person pedalpete; 24.02.2012
comment
Отлично, спасибо за ваше обновление @salt.racer, которое прояснило мне ситуацию. Я не делал спокойное обновление этой модели, о чем не знал до вашего комментария. Теперь у меня есть возможность успокоиться или нет, и я понимаю, почему я получаю такой ответ. - person pedalpete; 25.02.2012
comment
Просто продолжение этого - я сталкиваюсь с той же проблемой, и мне интересно, какое лучшее решение, в моем случае я также удаляю идентификатор при обновлении... но есть куча других значений, которые я возвращаю как встроенные атрибуты или возвращаемые методы (например, вычисляемые метки)... поэтому они также не могут быть обновлены. Есть ли соглашение о рельсах, чтобы справиться с этим более чисто? - person MBHNYC; 14.05.2013

Эти столбцы по умолчанию защищены от массового назначения и не могут быть установлены вручную. Но вы можете переопределить это поведение, определив метод:

def self.attributes_protected_by_default
  [] # ["created_at", "updated_at" ..other]
end

Это позволит вам назначить created_at и updated_at вручную.

person Syed Aslam    schedule 24.02.2012
comment
спасибо, Сайед, я не хочу переопределять их, мне интересно, что может заставить Rails думать, что я делаю? Есть идеи? - person pedalpete; 24.02.2012
comment
Тот факт, что временные метки (created_at, updated_at) и столбцы идентификаторов автоматически заполняются в ActiveRecord, если вы отправляете для них значения, то вы выполняете массовое назначение. - person Syed Aslam; 24.02.2012