I'm working on an AngularJS and Rails app that uses Google's definition API. The API returns a JSON response.
I would like to store the JSON response in my Words table. I'm issuing the API request through my Angular controller, then I'm trying to add the data to my Words table.
I'm getting an "Unpermitted parameters" error when I try to insert the JSON data. I've researched and this seems to be due to Rails 4 nested params.
I've tried adding nested brackets to my word_params method in Words controller but then get "Unpermitted parameters: dataType, numToShow, groupNumber, groupResult, sectionType, dictionary"... which is part of the API response.
Is there an easier way to permit the full JSON data without having to go through and specifically define each nested param in the controller's word_params method?
scheme.rb
create_table "words", force: :cascade do |t|
t.string "title"
t.json "full_data"
t.integer "list_id"
t.datetime "date"
end
Word controller
class WordsController < ApplicationController
respond_to :json
def create
list = List.find(params[:list_id])
word = list.words.create(word_params)
respond_with list, word
end
private
def word_params
params.require(:word).permit(:title, :date, :full_data => {})
end
end
app.js
//= require angular-rails-templates
//= require_tree .
angular.module('d-angular', ['ui.router', 'templates'])
// Set routing/configuration
// ------------------------------
.config(['$stateProvider', '$urlRouterProvider',
// Set state providers
function($stateProvider, $urlRouterProvider) {$stateProvider
// Home state
.state('home', {
url: '/home',
templateUrl: 'home.html',
controller: 'MainCtrl',
resolve: {
listPromise: ['lists', function(lists){
return lists.getAll();
}]
}
})
// Lists state
.state('lists', {
url: '/lists/{id}',
templateUrl: 'list.html',
controller: 'ListsCtrl',
resolve: {
list: ['$stateParams', 'lists', function($stateParams, lists) {
return lists.get($stateParams.id);
}]
}
})
$urlRouterProvider.otherwise('home');
}
])
// lists factory
// Factories are used to organize and share code across the app.
// ------------------------------
.factory('lists', ['$http',
function($http){
// create new obect with array of lists
var o = { lists: [] };
// get all lists
o.getAll = function() {
return $http.get('/lists.json').success(function(data){
angular.copy(data, o.lists);
});
};
// get specific list
o.get = function(id) {
return $http.get('/lists/' + id + '.json').then(function(res){
return res.data;
});
};
// create list
o.create = function(post) {
return $http.post('/lists.json', post).success(function(data){
o.lists.push(data);
});
};
// add word to list
o.addWord = function(id, word) {
return $http.post('/lists/' + id + '/words.json', word);
};
return o;
}
])
// Lists controller
// ------------------------------
.controller('ListsCtrl', ['$scope', 'lists', 'list', '$http',
// Main scope (used in views)
function($scope, lists, list, $http){
$scope.list = list; // get list by ID
// Add word function
$scope.addWord = function(){
// API URL
var api_url = "https://www.googleapis.com/scribe/v1/research?key=AIzaSyDqVYORLCUXxSv7zneerIgC2UYMnxvPeqQ&dataset=dictionary&dictionaryLanguage=en&query=";
// get data from API
$http.get(api_url + $scope.title)
// handle successful api request
.success(function (response) {
// push new word to array
lists.addWord(list.id, {
title: $scope.title,
date: new Date().toJSON().slice(0,10),
full_data: response
})
.success(function(word) {
$scope.list.words.push(word);
});
});
};
}
]);
Console response
Started POST "/lists/1/words.json" for ::1 at 2015-05-08 19:53:11 -0400
Processing by WordsController#create as JSON
Parameters: {"title"=>"fallacy", "date"=>"2015-05-08", "full_data"=>{"dataType"=>"dictionary", "numToShow"=>1, "groupNumber"=>0, "groupResult"=>{"query"=>"fallacy", "displayName"=>"<b>fal·la·cy</b>", "dataset"=>{"dataset"=>"dictionary"}, "score"=>1}, "sectionType"=>"dictionary", "dictionary"=>{"word"=>"fallacy", "dictionaryType"=>"STANDARD", "definitionData"=>[{"word"=>"fallacy", "pos"=>"Noun", "meanings"=>[{"meaning"=>"a mistaken belief, especially one based on unsound argument.", "examples"=>["the notion that the camera never lies is a fallacy"], "synonyms"=>[{"nym"=>"misconception", "nymResult"=>{"query"=>"misconception", "dataset"=>{"dataset"=>"dictionary"}}}, {"nym"=>"misbelief", "nymResult"=>{"query"=>"misbelief", "dataset"=>{"dataset"=>"dictionary"}}}, {"nym"=>"delusion", "nymResult"=>{"query"=>"delusion", "dataset"=>{"dataset"=>"dictionary"}}}, {"nym"=>"mistaken impression"}, {"nym"=>"error", "nymResult"=>{"query"=>"error", "dataset"=>{"dataset"=>"dictionary"}}}, {"nym"=>"misapprehension", "nymResult"=>{"query"=>"misapprehension", "dataset"=>{"dataset"=>"dictionary"}}}, {"nym"=>"misinterpretation"}, {"nym"=>"misconstruction", "nymResult"=>{"query"=>"misconstruction", "dataset"=>{"dataset"=>"dictionary"}}}, {"nym"=>"mistake", "nymResult"=>{"query"=>"mistake", "dataset"=>{"dataset"=>"dictionary"}}}], "submeanings"=>[{"meaning"=>"a failure in reasoning that renders an argument invalid."}, {"meaning"=>"faulty reasoning; misleading or unsound argument.", "examples"=>["the potential for fallacy which lies behind the notion of self-esteem"]}]}], "phoneticText"=>"ˈfaləsē", "wordForms"=>[{"word"=>"fallacy", "form"=>"noun"}, {"word"=>"fallacies", "form"=>"plural noun"}]}]}}, "list_id"=>"1", "word"=>{"title"=>"fallacy", "full_data"=>{"dataType"=>"dictionary", "numToShow"=>1, "groupNumber"=>0, "groupResult"=>{"query"=>"fallacy", "displayName"=>"<b>fal·la·cy</b>", "dataset"=>{"dataset"=>"dictionary"}, "score"=>1}, "sectionType"=>"dictionary", "dictionary"=>{"word"=>"fallacy", "dictionaryType"=>"STANDARD", "definitionData"=>[{"word"=>"fallacy", "pos"=>"Noun", "meanings"=>[{"meaning"=>"a mistaken belief, especially one based on unsound argument.", "examples"=>["the notion that the camera never lies is a fallacy"], "synonyms"=>[{"nym"=>"misconception", "nymResult"=>{"query"=>"misconception", "dataset"=>{"dataset"=>"dictionary"}}}, {"nym"=>"misbelief", "nymResult"=>{"query"=>"misbelief", "dataset"=>{"dataset"=>"dictionary"}}}, {"nym"=>"delusion", "nymResult"=>{"query"=>"delusion", "dataset"=>{"dataset"=>"dictionary"}}}, {"nym"=>"mistaken impression"}, {"nym"=>"error", "nymResult"=>{"query"=>"error", "dataset"=>{"dataset"=>"dictionary"}}}, {"nym"=>"misapprehension", "nymResult"=>{"query"=>"misapprehension", "dataset"=>{"dataset"=>"dictionary"}}}, {"nym"=>"misinterpretation"}, {"nym"=>"misconstruction", "nymResult"=>{"query"=>"misconstruction", "dataset"=>{"dataset"=>"dictionary"}}}, {"nym"=>"mistake", "nymResult"=>{"query"=>"mistake", "dataset"=>{"dataset"=>"dictionary"}}}], "submeanings"=>[{"meaning"=>"a failure in reasoning that renders an argument invalid."}, {"meaning"=>"faulty reasoning; misleading or unsound argument.", "examples"=>["the potential for fallacy which lies behind the notion of self-esteem"]}]}], "phoneticText"=>"ˈfaləsē", "wordForms"=>[{"word"=>"fallacy", "form"=>"noun"}, {"word"=>"fallacies", "form"=>"plural noun"}]}]}}, "date"=>"2015-05-08"}}
List Load (0.1ms) SELECT "lists".* FROM "lists" WHERE "lists"."id" = $1 LIMIT 1 [["id", 1]]
Unpermitted parameters: dataType, numToShow, groupNumber, groupResult, sectionType, dictionary
(0.1ms) BEGIN
Word Exists (0.2ms) SELECT 1 AS one FROM "words" WHERE ("words"."title" = 'fallacy' AND "words"."title" = 'fallacy') LIMIT 1
SQL (0.2ms) INSERT INTO "words" ("title", "date", "full_data", "list_id") VALUES ($1, $2, $3, $4) RETURNING "id" [["title", "fallacy"], ["date", "2015-05-08 00:00:00.000000"], ["full_data", "{}"], ["list_id", 1]]
(0.7ms) COMMIT
Completed 201 Created in 8ms (Views: 0.4ms | ActiveRecord: 1.4ms)