Глобализировать gem и сильные параметры Rails 4

Я использую rails 4.0.2 и globalize 4.0.0.alpha.3, но я не могу заставить запись данных в базы данных перевода со списком сильных параметров.

У меня есть модель предложения и проблема (OfferTranslationConcern)

    class Offer < ActiveRecord::Base
      include OfferTranslationConcern
    end

Концерн

    module OfferTranslationConcern
      extend ActiveSupport::Concern

      included do
        attr_accessor :attribute_translations

        translates :name, :city, :includes, :notes, :description, :slug
      end 
    end

Контроллер

    def update
      respond_to do |format|
        if @offer.update(offer_params)
          format.html { redirect_to @offer, notice: 'Offer was successfully updated.' }
          format.json { head :no_content }
        else
          format.html { render action: 'edit' }
          format.json { render json: @offer.errors, status: :unprocessable_entity }
        end
      end
    end       

И определение сильных параметров

    params.require(:user).permit('a lot of offer parameters', :attribute_translations => [:id, :name, :city, :includes, :notes, :description, :slug]
    )

Для переводов я использую, например, испанский и итальянский языки (it и es). Когда я обновляю предложение, я получаю Недопустимые параметры: it, es

Параметры выглядят так:

    "offer"=>{"attribute_translations"=>{"it"=>{"name"=>"dsfdsf", "city"=>"sdf", "includes"=>"sdfsdf", "notes"=>"sdfsd", "description"=>"fsdf"}, "es"=>{"name"=>"", "city"=>"", "includes"=>"", "notes"=>"", "description"=>""}}, "provider_id"=>"1",...a bunch of other stuff

Прямо сейчас я заставил его работать с этим определением сильных параметров

    def offer_params
      params.require(:offer).permit! 
    end 

Это работа, но я не думаю, что это лучший способ. Итак, мой вопрос: есть ли способ определить список параметров и заставить это работать?


person Marko Jurinčič    schedule 05.01.2014    source источник


Ответы (2)


Вы декларируете это:

:attribute_translations => [:id, :name, :city, :includes, :notes, :description, :slug]

но вы получаете это:

"attribute_translations"=>{"it"=>{"name"=>"dsfdsf", "city"=>"sdf", "includes"=>"sdfsdf", "notes"=>"sdfsd", "description"=>"fsdf"}

Если :id => "it", то вам нужно объявить это так:

:attribute_translations => [:id => [:name, :city, :includes, :notes, :description, :slug]]

По крайней мере, это то, что ваша форма думает, что вы хотите для формата. Поэтому вам нужно либо сопоставить формат вашей формы с вашими параметрами, либо ваши параметры с вашей формой.

Как вы сказали, метод permit! не лучший выбор, он очень небезопасен, так как он заносит в белый список все, что ему передается. Если вам нужно передать неизвестное количество параметров, вам придется использовать довольно сложный блок. Если это так, прочитайте это: Недопустимые параметры для Динамические формы в Rails 4

person Beartech    schedule 06.01.2014

Избегайте этой боли с помощью драгоценного камня globalize-accessors. attr-accessor устарел, гем решает эту проблему напрямую. Модель требует однострочника после объявления столбцов перевода.

globalize_accessors :locales => [:it, :en, :fr, :es, :de, :gr], :attributes => [:name]

Контроллер также является однострочным (если все поля переведены), двумя, если вы смешиваете и сочетаете

params.require(:channel).permit(*Channel.globalize_attribute_names)

Помощник представления lang слишком упрощен, особенно если у вас много локалей и много столбцов. Оставить его на своих устройствах - это просто поток... Но немного руби и полагаясь на то, что локали последовательно поданы, визуальные эффекты значительно улучшаются:

 <% Channel.globalize_attribute_names.each do |lang| %>
   <% if lang[-2, 2] == "it" %>
     <div class="row highlight">
       <h5><%= lang[0..-4] %></h5>
   <% end %>
     <div class=" .... columns">
       <%= lang[-2, 2] %>
       <%= f.text_area lang, rows: "3" %>
     </div>
   <% if (lang[-2, 2] == "gr") %>
     </div>
   <% end %>
 <% end %>

Примечание. Показанный здесь макет должен следовать порядку локалей (здесь: первый: it, последний:gr), как определено в application.rb... во избежание проблем

person Jerome    schedule 10.10.2015