Globalize gem and Rails 4 strong parameters

1.5k views Asked by At

I am using rails 4.0.2 and globalize 4.0.0.alpha.3, but i can not get the thing to write the data into the translation databases with a list of strong parameters.

I have an offer model and a concern (OfferTranslationConcern)

    class Offer < ActiveRecord::Base
      include OfferTranslationConcern
    end

The concern

    module OfferTranslationConcern
      extend ActiveSupport::Concern

      included do
        attr_accessor :attribute_translations

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

The controller

    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       

And the definition of the strong parameters

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

For the translations I am using for example the spanish and italian language (it and es). When I update the offer I get Unpermitted parameters: it, es

The parameters looks like this:

    "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

Right now I made it work with this definition of strong parameters

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

This work, but I don't think this is the best way. So, my question is if there is a way to define the list of parameters and make this work?

2

There are 2 answers

0
Beartech On BEST ANSWER

You are declaring this:

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

but you are receiving this:

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

If :id => "it" then you need to declare it like this:

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

At least that is what your form thinks you want for the format. So you need to either match your form's format to your params or your params to your form.

The permit! method is not the best choice as you said, it's very insecure as it will whitelist anything passed to it. If you need to submit an unknown number of parameters you have to use a rather complex block. If that is the case, read this: Unpermitted parameters for Dynamic Forms in Rails 4

0
Jerome On

Avoid this pain via the globalize-accessors gem. attr-accessor being deprecated, the gem addresses this directly. Model requires a one-liner after our translations columns declaration

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

Controller is also a one-liner (if all fields are translated), two if you mix and match

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

The View helper lang is oversimplified, particularly if you have many locales and many columns. Leaving it at its devices is just a stream... But a little ruby and relying on the fact that the locales are consistently served up, visuals improve significantly:

 <% 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 %>

Note: the layout shown here needs to follow the order of the locales (here: first: it, last:gr) as defined in application.rb... to avoid any problems