如何解决“无法批量分配受保护的属性:translations_attributes”错误?
我正在使用Ruby on Rails(3.2.2), globalize3 (0.2.0)和batch_translations (0.1.2)ruby-gems。 我想解决使用batch_translations ruby-gem时产生的以下问题:
ActiveModel::MassAssignmentSecurity::Error in Admin::ArticlesController#update Can't mass-assign protected attributes: translations_attributes
在我的ROOT_RAILS/Gemfile
文件中,我有:
... gem 'globalize3' gem 'batch_translations'
在我的ROOT_RAILS/app/models/admin/article.rb
文件中,我有:
class Admin::Article < ActiveRecord::Base translates :title # This is needed to make the batch_translations to work. accepts_nested_attributes_for :translations ... end
在我的ROOT_RAILS/app/views/admin/articles/_form.html.erb
文件中,我有:
admin_article_path) do |f| %>
English translation: Italiano translation: <% # Note: I am using the '<%= f...' instad of '
在我的ROOT_RAILS/app/controllers/admin/articles_controller.html.erb
文件中,我有:
class Admin::ArticlesController < ApplicationController def update @admin_article = Article.find(params[:id]) respond_to do |format| if @admin_article.update_attributes(params[:article]) format.html { redirect_to admin_article_path(@admin_erticle), notice: 'Article was successfully updated.' } format.json { head :no_content } else format.html { render action: "edit" } format.json { render json: @admin_article.errors, status: :unprocessable_entity } end end end ... end
当我显示编辑表单时,所有工作,但当我提交该表单时,我得到上面提到的错误。 如何解决上述错误?
UPDATE
我在ROOT_RAILS/app/models/admin/article.rb
文件中使用以下代码找到了解决方案:
class Admin::Article < ActiveRecord::Base translates :title attr_accessible :translations_attributes accepts_nested_attributes_for :translations ... end
…但是确实可以使用:translations_attributes
?
这是最新版本的rails的一个问题,因为他们修补了它。 您可以在配置中更改它。 有关详细信息,请参见http://weblog.rubyonrails.org/2012/3/30/ann-rails-3-2-3-has-been-released/ 。
我可以确认你的attr_accessible解决方案是正确的。
我有同样的问题。 我认为这是一个很好的解决方案:
在我的Gemfile文件中,我有:
gem 'globalize3', '~> 0.2.0' gem 'batch_translations', '~> 0.1.2'
在我的application.rb文件中,我有:
config.i18n.available_locales = [:es, :en]
在我的模型(category.rb)中,我有:
class Category < ActiveRecord::Base attr_accessible :name, :translations_attributes translates :name accepts_nested_attributes_for :translations, :reject_if => proc { |attributes| attributes['name'].blank? } validates :name, :presence => true end Category::Translation.class_eval do attr_accessible :name end
在我的帮手(application_helper.rb)中,我有:
module ApplicationHelper def find_available_locales locales = {} I18n.available_locales.each { |locale| locales[locale] = t("locale_selector.#{locale}") } locales end def available_locales @available_locales ||= find_available_locales end end
在我的翻译文件中,我有:
en.yml
en: locale_selector: es: 'Spanish' en: 'English'
es.yml
en: locale_selector: es: 'Español' en: 'Inglés'
在我的视图文件(_form.html.erb)中,我有:
<%= form_for @category, html: { class: 'form-horizontal' } do |f| %> <% available_locales.each_pair do |locale, name_locale| -%> <% if locale == I18n.locale -%> <%= f.label :name, class: 'control-label' %> <%= f.text_field :name, class: 'text_field' %> (<%= name_locale %>) <% else -%> <%= f.globalize_fields_for locale do |g| -%> <%= g.label :name, class: 'control-label' %> <%= g.text_field :name, class: 'text_field' %> (<%= name_locale %>) <% end -%> <% end -%> <% end -%> <%= f.submit nil, class: 'btn btn-primary' %> <%= link_to t('.cancel', default: t("helpers.links.cancel")), categories_path, class: 'btn' %> <% end %>
正如您所看到的,问题是rails 3.2需要知道哪些属性可以访问,但globalize不指定此属性。 所以我在我的模型(类别)中用attr_accessible定义了这个,但是我也需要为翻译添加这个,因此我在同一个文件中添加几行来设置这个模型中每个翻译的可访问名称(Category :: Translation) .class_eval)。
是。 Rails可能配置为仅允许批量分配明确允许的属性。
# This is mass assignment Model.find(params[id]).update_attributes params[:model]
白名单方法是为了安全而强制执行的。 params[:model]
可以包含任何内容,甚至是表单中没有的属性。 攻击者可以利用此function并将admin: true
与其他值一起发送。
如果没有attr_accessible
,攻击者将被授予管理员权限。 但是,如果:admin
未在白名单中,则update_attributes
将不会更新该特定属性。
gem可能是引擎盖下的大规模分配。 确保允许他们写入自己的属性。