Reputation: 1594
My app is a Rails API backend and VueJS via Nuxt front end.
I have a form where one of the inputs is a select and I'm using vue-multiselect. The select options are values from a different table, where I want to display the name field, but submit the ID.
I am able to display the options in the drop drown ok, and I'm also submitting other values in the form, but the ID is not working.
Rails console shows the error of distillery_id
not being a permitted parameter, although I do have this set in the controller.
Started POST "/api/v1/gins" for ::1 at 2019-02-01 13:25:38 +0000
Processing by Api::V1::GinsController#create as HTML
Parameters: {"gin_name"=>"distillery_id", "description"=>"distillery_id should be submitted", "distillery_id"=>{"id"=>3, "distillery_name"=>"Gordon's", "snippet"=>nil, "description"=>nil, "website"=>nil, "country"=>"United Kingdom", "created_at"=>"2019-01-29T13:46:15.088Z", "updated_at"=>"2019-01-29T13:46:15.088Z", "slug"=>nil}, "abv"=>"0", "snippet"=>"distillery_id now?", "gin"=>{"gin_name"=>"distillery_id", "snippet"=>"distillery_id now?", "description"=>"distillery_id should be submitted", "abv"=>"0", "distillery_id"=>{"id"=>3, "distillery_name"=>"Gordon's", "snippet"=>nil, "description"=>nil, "website"=>nil, "country"=>"United Kingdom", "created_at"=>"2019-01-29T13:46:15.088Z", "updated_at"=>"2019-01-29T13:46:15.088Z", "slug"=>nil}}}
Unpermitted parameter: :distillery_id
gins_controller.rb
...
def gin_params
params.require(:gin).permit(:gin_name, :alcoholic, :snippet, :description, :abv, :distillery_id)
end
...
new.vue
<template>
<section class="container">
<div>
<h1>Gins</h1>
<form @submit.stop.prevent="addGin">
<h2>New Gin</h2>
<p>
<label for="gin_name" class="input-label">Title:</label>
<input id="gin_name" v-model="gin_name" type="gin_name" name="gin_name" class="input">
</p>
<p>
<label for="snippet" class="input-label">Snippet:</label>
<input id="snippet" v-model="snippet" type="text" name="snippet" class="input">
</p>
<p>
<label for="description" class="input-label">Description:</label>
<input id="description" v-model="description" type="textarea" name="description" class="input">
</p>
<p>
<label for="abv" class="input-label">ABV%:</label>
<input id="abv" v-model="abv" type="number" name="abv" class="input">
</p>
<div>
<label for="distillery_id" class="input-label">Distillery:</label>
<multiselect
v-model="distillery_id"
track_by="distillery_id"
:options="options"
:searchable="true"
placeholder="Choose One Distillery"
:custom-label="label"
>
</multiselect>
</div>
<p>
<input type="submit" value="Submit" class="button">
</p>
</form>
</div>
</section>
</template>
<script>
import axios from 'axios'
import Multiselect from 'vue-multiselect'
export default {
components: { Multiselect },
data() {
return {
gin_name: '',
snippet: '',
description: '',
abv: '',
distillery_id: '',
options: []
}
},
mounted() {
this.getDistilleries()
},
methods: {
label(option) {
return `${option.distillery_name}`
},
addGin() {
axios.post('http://localhost:4000/api/v1/gins', {
gin_name: this.gin_name, description: this.description, distillery_id: this.distillery_id, abv: this.abv, snippet: this.snippet
})
.then((response) => {})
console.log()
},
getDistilleries(req) {
axios.get('/api/v1/distilleries')
.then((res) => {
this.options = res.data
})
.catch((error) => {
console.log(error)
})
}
}
}
</script>
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style>
<style>
</style>
Based on the console, I suspect this is a rails issue rather than vue, but that permitted params looks good to me.
Any suggestions what else could be amiss?
Upvotes: 0
Views: 371
Reputation: 298
Caution, this is untested. But, after having a quick look at VueMultiselect's docs and your Vue component, it looks like your distillery_id v-model is being set to a single distillery object. Which I believe @UdAY revealed in the comments. So your POST data can be changed to:
addGin() {
axios.post('http://localhost:4000/api/v1/gins', {
gin_name: this.gin_name,
description: this.description,
distillery_id: this.distillery_id.id, //this.distillery_id is being set as an object and you just need the id prop here
abv: this.abv, snippet: this.snippet
})
Upvotes: 1
Reputation: 1300
Have you tried to use a filter to get the good values?
addGin() {
let myId = options.filter(o => distillery_id.some(d => d.distillery_id === o.distillery_id));
axios.post('http://localhost:4000/api/v1/gins', {
gin_name: this.gin_name,
description: this.description,
distillery_id: myId,
abv: this.abv,
snippet: this.snippet
}).then(console.log)
},
I'm not sut that this works, check the code before use.
Other way is debug the code in the line and check how you could get the id:
addGin(argument1, argument2, argument3) {
debugger; // The code will stop here, check this object to get the data and change the code!
axios.post('http://localhost:4000/api/v1/gins', {
gin_name: this.gin_name,
description: this.description,
distillery_id: this.distillery_id,
abv: this.abv,
snippet: this.snippet
}).then(console.log)
},
I suggest to change multiselect to vue-select The docs seems more readable.
Hope it helps :)
Upvotes: 0