Динамическое хеш-поле в Mongoid с использованием сильных параметров

Таким образом, не существует простого способа разрешить хеш-поле с сильными параметрами. Конечно, это может быть серьезной проблемой параметров, но мне любопытно, есть ли обходной путь. У меня есть модель с некоторыми полями...

field :name, type: String
field :email, type: String
field :other_stuff, type: Hash, default: {}

Теперь я мог просто разрешить все:

params.require(:registration).permit!

Но это не очень хорошая идея, и я хотел бы сделать что-то вроде...

params.require(:registration).permit(:name, :email, {other_stuff: {} })

Однако это кажется невозможным с сильными параметрами, невозможно просто внести хэш в белый список как свойство (ура, для API ActiveRecord, ориентированных на SQL!). Любые идеи, как это можно сделать, или лучше всего отправить патч Rails, чтобы разрешить этот сценарий.


person Chris Nicola    schedule 27.08.2013    source источник


Ответы (3)


Хорошо, изучив это, я нашел элегантное решение, которое я тоже начну использовать:

params.require(:registration).permit(:name).tap do |whitelisted|
  whitelisted[:other_stuff] = params[:registration][:other_stuff]
end

источник: https://github.com/rails/rails/issues/9454#issuecomment-14167664

person Arthur Neves    schedule 27.08.2013
comment
Эээээээээээээээээээээээээээ. Но вы правы, похоже, так и должно быть. - person Chris Nicola; 27.08.2013

При необходимости вложенные атрибуты также могут быть разрешены следующим образом:

def create_params
  params[:book]["chapter"].permit(:content)
end
person Jeremy Lynch    schedule 07.09.2014

Для поля, допускающего вложенные хэши, я использую следующее решение:

def permit_recursive_params(params)
  params.map do |key, value|
    if value.is_a?(Array)
      { key => [ permit_recursive_params(value.first) ] }
    elsif value.is_a?(Hash) || value.is_a?(ActionController::Parameters)
      { key => permit_recursive_params(value) }
    else
      key
    end
  end
end

Чтобы применить его, например, к параметру values, вы можете использовать его следующим образом:

def item_params
  params.require(:item).permit(values: permit_recursive_params(params[:item][:values]))
end
person Koen.    schedule 21.03.2016