Rails - Strong parameters with empty arrays

后端 未结 5 1786
星月不相逢
星月不相逢 2021-02-01 13:37

I\'m sending an array of association ids, say foo_ids to my controller. To permit an array of values, I use:

params.permit(foo_ids: [])
5条回答
  •  暗喜
    暗喜 (楼主)
    2021-02-01 14:37

    This solution won't work for all cases:

    params.require(:photo).permit(:tags, tags: [])
    

    For example, if you are using MongoDB and you have a tag_ids array, which stores the ids in a has_many collection, your tag_ids attribute MUST be an array if you specify "type: Array" for the attribute in your model. Consequently, it won't work to send tag_ids with a nil value even if you do this:

     params.require(:photo).permit(:tag_ids, tag_ids: [])
    

    Mongoid, the official Ruby adapter for MongoDB, will complain the value of tag_ids must be an array.

    The solution is you can indeed send an empty array via your form! And it doesn't need to be a json request. You can simply use remote: true on your form and send it via type: :js. How to do it? Simple. Just add a hidden input in your form and set its value to an empty string:

    <%= form_for @user, remote: true, html: { class: 'form' } do |f| %>
      <%= select_tag("#{f.object_name}[tag_ids][]", options_for_select(Tag.all.collect {|t| [t.name, c.id]}, selected: f.object.tag_ids), { class: 'form-control', multiple: 'multiple' }) %>
      <%= hidden_field_tag "#{f.object_name}[tag_ids][]", '' %>
      <%= f.submit class: 'btn ink-reaction btn-raised btn-primary' %>
    <% end %>
    

    This here is the key:

    <%= hidden_field_tag "#{f.object_name}[tag_ids][]", '' %>
    

    Your attribute will be stored as an empty array in your database. Note I only tested this with Mongoid, but I assume it carries the same functionality in ActiveRecord.

提交回复
热议问题