2015-05-08 37 views
0

我正在使用Google定义API的AngularJS和Rails应用程序。该API返回一个JSON响应。Rails 4未经允许的参数 - JSON数据

我想将JSON响应存储在我的Words表中。我通过我的Angular控制器发布API请求,然后我试图将数据添加到我的Words表中。

当我尝试插入JSON数据时,出现“Unpermitted parameters”错误。我研究过,这似乎是由于Rails 4 nested params

我已经尝试添加嵌套括号到Word控制器中的word_params方法,但随后得到“不允许的参数:dataType,numToShow,groupNumber,groupResult,sectionType,字典”...这是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 

字控制器

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

请注意,如果您在指向散列的密钥中使用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