2017-09-20 2 views
0

Je tente d'envoyer un certain nombre d'éléments cochés dans un contrôleur Rails, mais je n'arrive pas à le faire fonctionner correctement.POSTing des éléments de formulaire Vue dans un contrôleur Rails 5.1

Dans ma forme, j'ai:

<%= form_for(listing, html: { id: listing.id, class: 'listing_form' }) do |f| %> 
    ... 

    <div v-for="(item, idx) in items"> 
    <label class="custom-control custom-checkbox"> 
     <input type="checkbox" class="custom-control-input" v-model="checkedItems[idx]" :value="item.id"> 
     <span class="custom-control-indicator"></span> 
     <span class="custom-control-description">{{ item.text }}</span> 
    </label> 
    </div> 

    ... 

    <div class="actions"> 
    <%= f.submit class: 'btn btn-success', 'v-on:click.prevent': 'submitListing' %> 
    </div> 
<% end %> 

et mon code Vue ressemble à ceci:

if(document.getElementById('listing-multistep') != null) { 
    Vue.http.headers.common['X-CSRF-Token'] = document.querySelector('input[name="authenticity_token"]').getAttribute('value'); 
    var listingForm = document.getElementsByClassName('listing_form')[0]; 
    var id = listingForm.dataset.id; 

    const listingForm = new Vue({ 
    el: '#listing-multistep', 
    data: { 
     id: id, 
     name: '', 
     city: '', 
     state: '', 
     address: '', 
     items: [ 
      {id: 0, text: "Item1"}, 
      {id: 1, text: "Item2"}, 
      {id: 2, text: "Item3"} 
     ], 
     checkedItems: [] 
    }, 
    methods: { 
     submitListing: function() { 
     var itemNames = [] 
     var checkedIndices = [] 

     // Probably a better way to do this... 
     // Get the indices of all checkedItems that are true 
     this.checkedItems.forEach((elt, idx) => { 
      if(elt === true){ checkedIndices.push(idx) } 
     }); 
     // Get the value of all the above indices  
     this.items.map((item) => { 
      if(checkedIndices.includes(item.id)){ 
      itemNames.push(item.text); 
      } 
     }); 

     var listingObj = { 
      id: this.id, 
      name: this.name, 
      city: this.city, 
      state: this.state, 
      address: this.address, 
      items: itemNames // <--- this is an array of items which isn't filtering through to Rails in the POST request 
     } 

     if(this.id == null) { 
      console.log(listingObj) 
      // POST the listingObj if it's a new listing 
      this.$http.post('/listings', {listing: listingObj}).then(
      response => { 
       window.location = `/listings/${response.body.id}` 
      }, response => { 
      console.log(response) 
      }) 
     } else { 
      // PUT the listingObj if it's an existing listing 
      this.$http.put(`/listings/${this.id}`, {listing: listingObj}).then(
      response => { 
       window.location = `/listings/${response.body.id}` 
      }, response => { 
      console.log(response) 
      }) 
     } 
     } 
    } 

Alors que la plupart des données sont envoyées à travers et la liste est générée, le problème est que le tableau items ne parvient pas au contrôleur Rails.

Ma base de données est PostgreSQL et les éléments déposés dans la base de données est définie comme suit dans schema.rb (donc un champ tableau devrait être possible):

t.text "items", default: [], array: true 

Je permettais de passer à travers les fortes params dans mon contrôleur:

class ListingsController < ApplicationController 

    ... 

    private 
    def listing_params 
    params.require(:listing).permit(
     :name, 
     :city, 
     :state, 
     :address, 
     :items) 
    end 
end 

mais ne peut pas comprendre pourquoi champ items du listingOb n'est pas porté à travers Rails. Une idée de pourquoi cela pourrait être? Merci d'avance

Répondre

1

Les paramètres forts dans Rails pour autoriser un champ tableau ressemble à ceci:

def listing_params 
    params.require(:listing).permit(
    :name, 
    :city, 
    :state, 
    :address, 
    :items => [] 
) 
end 

fonctionne maintenant!