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

Използвам rails като страна на сървъра на backbone.js сайт, следователно непрекъснато предавам обектите на rails напред-назад.

Забелязвам грешки в релсите, връщащи 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

РЕДАКТИРАНЕ1 (за да се отговори на коментара относно връщането на идентификатора):

Ако използвате Rails REST модела и извиквате 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
Но актуализацията винаги изисква идентификаторът да бъде върнат, но не и актуализиран. Мисля, че това беше най-голямата ми грижа. Ако не изпратя времевите клейма на гръбнака, те няма да бъдат върнати, но трябва да изпратя идентификатора. Предполагам, че затова съм толкова объркан. Виждам как rails ме „защитава“, но бих искал да знам защо виждам това точно в този случай. - person pedalpete; 24.02.2012
comment
Страхотно, благодаря за вашата актуализация @salt.racer, която ми изяснява. Не правех спокойна актуализация на този модел, което не разбрах до вашия коментар. Сега имам възможността да се отпусна или не и да разбера защо получавам този отговор. - person pedalpete; 25.02.2012
comment
Просто продължение на това — срещам същия проблем и съм любопитен кое е най-доброто решение, в моя случай също изтривам идентификатора при актуализация... но има куп други стойности, които връщам като вградени атрибути или връщания метод (като изчислени етикети)...така че и те не могат да бъдат актуализирани. Има ли rails конвенция, която да се справи с това по-чисто? - 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
благодаря Syed, не искам да ги пренебрегвам, чудя се какво може да е причината Rails да мисли, че го правя? Някакви идеи? - person pedalpete; 24.02.2012
comment
Фактът, че клеймата за време (created_at, updated_at) и колоните с id се попълват автоматично в ActiveRecord, ако изпращате стойности за тях, тогава масово присвоявате. - person Syed Aslam; 24.02.2012