我正在开发使用Google定义API的AngularJS和Rails应用。 API返回JSON响应。
我想将JSON响应存储在Words表中。我通过Angular控制器发出API请求,然后我尝试将数据添加到Words表中。
我得到了一个"未经许可的参数"我尝试插入JSON数据时出错。我已经研究过,这似乎是由于Rails 4 nested params。
我尝试在Words控制器中为word_params方法添加嵌套括号,但后来得到"未经许可的参数:dataType,numToShow,groupNumber,groupResult,sectionType,dictionary" ...这是API响应。
是否有更简单的方法来允许完整的JSON数据而无需在控制器的word_params方法中专门定义每个嵌套参数?
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控制器
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);
});
});
};
}
]);
控制台响应
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)
答案 0 :(得分:1)
请注意,如果在指向哈希的键中使用permit,则不会允许所有哈希。您还需要指定哈希中的哪些属性应列入白名单。
http://edgeapi.rubyonrails.org/classes/ActionController/Parameters.html#method-i-permit
Rails并没有真正提供一种直接的方法来盲目地将嵌套参数哈希列入白名单。
你可以做一些像hackey这样的事情:
params.require(:word).permit(:full_data).tap do |whitelisted|
whitelisted[:full_data] = params[:word][:full_data]
end