2

私はRubyonRails(3.2.2)、globalize3(0.2.0)、batch_translations(0.1.2)ruby-gemsを使用しています。batch_translationsruby-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ファイルには次のものがあります。

<%= form_for(@admin_article, :url => admin_article_path) do |f| %>
    <%= f.label :title %><br />
    English translation:
    <%= f.text_field :title %>

    Italiano translation:
    <%
      # Note: I am using the '<%= f...' instad of '<% f...' otherwise
      # batch_translations doesn't output the input field in the
      # front-end content.
    %>
    <%= f.globalize_fields_for :it do |g| %>
      <%= g.text_field :title %>
    <% end %>
<% end %>

私の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

編集フォームを表示するとすべてが機能しますが、そのフォームを送信すると、上記のエラーが発生します。 上記のエラーを解決するにはどうすればよいですか?


アップデート

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アクセス可能にすることは確かですか?

4

3 に答える 3

4

私も同じ問題を抱えていました。これは良い解決策だと思います:

私の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 -%>
      <div class="control-group">
        <%= f.label :name, class: 'control-label' %>
        <div class="controls">
          <%= f.text_field :name, class: 'text_field' %> <i>(<%= name_locale %>)</i>
        </div>
      </div>
    <% else -%>
      <%= f.globalize_fields_for locale do |g| -%>
        <div class="control-group">
          <%= g.label :name, class: 'control-label' %>
          <div class="controls">
            <%= g.text_field :name, class: 'text_field' %> <i>(<%= name_locale %>)</i>
          </div>
        </div>
      <% end -%>
    <% end -%>
  <% end -%>

  <div class="form-actions">
    <%= f.submit nil, class: 'btn btn-primary' %>
    <%= link_to t('.cancel', default: t("helpers.links.cancel")),
                categories_path, class: 'btn' %>
  </div>
<% end %>

ご覧のとおり、問題は、rails 3.2がアクセス可能な属性を知る必要があることですが、globalizeはこれを指定していません。したがって、モデル(Category)でattr_accessibleを使用してこれを定義しますが、翻訳にもこれを追加する必要があります。このため、同じファイルに数行を追加して、このモデル(Category :: Translation)の各翻訳でアクセス可能な名前を設定します。 .class_eval)。

于 2012-09-24T11:33:49.697 に答える
3

これは、最新バージョンのRailsにパッチが適用されているため、問題になります。設定で変更できます。詳細については、 http://weblog.rubyonrails.org/2012/3/30/ann-rails-3-2-3-has-been-released/を参照してください。

attr_accessibleソリューションが正しいことを確認できます。

于 2012-04-13T11:37:15.003 に答える
0

はい。Railsは、明示的に許可された属性の一括割り当てのみを許可するように構成されている可能性があります。

# This is mass assignment
Model.find(params[id]).update_attributes params[:model]

ホワイトリストアプローチは、セキュリティのために実施されます。params[:model]フォームで使用できなかった属性も含めて、何でも含めることができます。攻撃者はこれを利用admin: trueして、他の値と一緒に送信できます。

がなければattr_accessible、攻撃者には管理者権限が付与されます。ただし、:adminホワイトリストに含まれていなかった場合、update_attributesその特定の属性は更新されませんでした。

宝石はおそらくボンネットの下で大量に割り当てられています。彼らが彼ら自身の属性に書くことを許可することを確認してください。

于 2012-04-13T11:52:23.997 に答える