setting hstore in rails4, dynamic key/values
Asked Answered
D

3

5

I'm playing around with Hstore for the first time in a rails4 app, and I am using javascript in a form to build out dynamic form fields for the hstore column (:schema)

In rails 4 I dont need to add any setter/getter method in my model, correct?

In my form i am building dynamic input fields and allowing the user to set the key/value pairs. Much like the Hstore Heroku Demo App

So basically my form would have inputs like

input name="app[schema][dynamic_key1]" value="whatever value"
input name="app[schema][dynamic_key2]" value="whatever value2"

In my App Controller:

def app_params
  params.require(:app).permit(:name, :title, :schema )
end

However, when i create a new App record, my schema hstore values are not saving. I saw some things about making the strong param for :schema => [] but that still does not work.

Since I do not know what these values will be, i cant setup store_accessors for these like I have seen in a lot of examples.

Difficulty answered 27/9, 2013 at 15:27 Comment(1)
Can you please add (important part with form_for) full code for layout/controller ?Including
D
11

found this here: http://guides.rubyonrails.org/action_controller_overview.html#more-examples

and in my controller I used:

def app_params
  params.require(:app).permit(:name, :title).tap do |whitelisted|
    whitelisted[:schema] = params[:app][:schema]
  end
end
Difficulty answered 27/9, 2013 at 20:18 Comment(2)
I think you might want to update your answer according to that rails guide you have pointed out. They currently use this code: params.require(:product).permit(:name, data: params[:product][:data].try(:keys))Jugular
Per the docs for 5.1, Alexander's solution still works and relieved me of my hstore/strong params issues! Thanks!Hifalutin
W
1

I think Rails must have simplified this in recent versions (current as of 5.2.3 at least)... and much cleaner/easier:

params.require(:parent).permit(:name, :whatever, data: {})

This will allow and store any/all attributes of data into an hstore field. An example of POSTing or PUTing a data nested attribute via HTML:

<input type="text" name="parent[data][your_super_custom_nested_data] />`

4th example down: https://guides.rubyonrails.org/action_controller_overview.html#more-examples

Wallache answered 27/8, 2019 at 8:22 Comment(0)
T
0

Here's a way that also allows deleting of the hstore keys by submitting empty parameters.

In your ApplicationController add this method:

# Returns the hstore keys to be whitelisted.
#
# @param key [Symbol] the name of the hstore field
# @param params [Hash] the parameters for the hstore field
#
# @return [{Symbol => Array<Symbol>}, Symbol]
def permit_hstore_params(key, hstore_params)
  keys = hstore_params.try(:keys)

  # Return key if params are empty, 
  # this allows the hstore key to be removed.
  return key if keys.blank?

  # Otherwise, return the keys to be whitelisted
  { key => keys }
end

Example:

class DynamicRecord < ActiveRecord::Base
  store_accessor :metadata
end

class DynamicRecordController < ApplicationController
  # ...

  def dynamic_model_params
    params
      .require(:dynamic_model)
      .permit(:name, permit_hstore_params(:metadata, params[:dynamic_model][:metadata]))
  end
end
Thrombin answered 8/10, 2014 at 19:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.