Search code examples
ruby-on-railsrubyhashhidden-field

Passing hash as values in hidden_field_tag


I am trying to pass some filters in my params through a form like so:

hidden_field_tag "filters", params[:filters]

For some reason the params get changed in the next page. For example, if params[:filters] used to be...

"filters"=>{"name_like_any"=>["apple"]} [1]

...it gets changed to...

"filters"=>"{\"name_like_any\"=>[\"apple\"]}" [2]

note the extra quotations and backslashes in [2] when compared to [1].

Any ideas? I'm attempting to use this with searchlogic for some filtering, but I need it to persist when I change change objects in forms. I would prefer not to have to store it in session.


Solution

  • You actually want/need to 'serialize' a hash using hidden fields.

    Add this to your ApplicationHelper :

      def flatten_hash(hash = params, ancestor_names = [])
        flat_hash = {}
        hash.each do |k, v|
          names = Array.new(ancestor_names)
          names << k
          if v.is_a?(Hash)
            flat_hash.merge!(flatten_hash(v, names))
          else
            key = flat_hash_key(names)
            key += "[]" if v.is_a?(Array)
            flat_hash[key] = v
          end
        end
    
        flat_hash
      end
    
      def flat_hash_key(names)
        names = Array.new(names)
        name = names.shift.to_s.dup 
        names.each do |n|
          name << "[#{n}]"
        end
        name
      end
    
      def hash_as_hidden_fields(hash = params)
        hidden_fields = []
        flatten_hash(hash).each do |name, value|
          value = [value] if !value.is_a?(Array)
          value.each do |v|
            hidden_fields << hidden_field_tag(name, v.to_s, :id => nil)          
          end
        end
    
        hidden_fields.join("\n")
      end
    

    Then, in view:

    <%= hash_as_hidden_fields(:filter => params[:filter]) %>
    

    This should do the trick, even if you have a multilevel hash/array in your filters.

    Solution taken http://marklunds.com/articles/one/314